more refactor of play_side and game_end_exception.hpp
Instead of having different exceptions (ai_end_turn_exception, end_level_exception and restart_turn_exception) we now have one exception (return_to_play_side_exception) that is used to escape from play_ai_turn or play_slice and is catched in the play_side related functions. The information why we returned to play_side is already stored in the playsingle_controller object. That is also why we do not need the possible_end_play_signal return value anymore. play_controller::check_victory does not throw exceptions anymore Also do_replay and thus turn_info::process_network_data don't throw exceptions anymore when the scenario is finished by victory or defeat. Instead it returns REPLAY_FOUND_END_LEVEL, this means return_to_play_side_exception is not thrown during replay at all. this also fixed up a previous commit 'refactor play_side' where accidently play_idle_loop was called instead of play_human_turn in play_side.
This commit is contained in:
parent
62cea304b3
commit
fb68590637
30 changed files with 370 additions and 485 deletions
|
@ -1497,25 +1497,8 @@ static void advance_unit_at(const map_location& loc, const ai::unit_advancements
|
|||
void attack_unit_and_advance(const map_location &attacker, const map_location &defender,
|
||||
int attack_with, int defend_with, bool update_display,
|
||||
const ai::unit_advancements_aspect& ai_advancement)
|
||||
{ try
|
||||
{
|
||||
attack_unit(attacker, defender, attack_with, defend_with, update_display);
|
||||
}
|
||||
catch(end_level_exception&)
|
||||
{
|
||||
|
||||
unit_map::const_iterator atku = resources::units->find(attacker);
|
||||
|
||||
if (atku != resources::units->end()) {
|
||||
advance_unit_at(attacker, ai_advancement);
|
||||
}
|
||||
|
||||
unit_map::const_iterator defu = resources::units->find(defender);
|
||||
if (defu != resources::units->end()) {
|
||||
advance_unit_at(defender, ai_advancement);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
{
|
||||
attack_unit(attacker, defender, attack_with, defend_with, update_display);
|
||||
unit_map::const_iterator atku = resources::units->find(attacker);
|
||||
if (atku != resources::units->end()) {
|
||||
advance_unit_at(attacker, ai_advancement);
|
||||
|
|
|
@ -1270,6 +1270,7 @@ size_t move_unit_and_record(const std::vector<map_location> &steps,
|
|||
set_scontext_synced sync;
|
||||
size_t r = move_unit_internal(undo_stack, show_move, interrupted, mover);
|
||||
resources::controller->check_victory();
|
||||
resources::controller->maybe_throw_return_to_play_side();
|
||||
sync.do_final_checkup();
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ void action_result::execute()
|
|||
if (is_success()){
|
||||
try {
|
||||
do_execute();
|
||||
} catch (end_level_exception&) {
|
||||
} catch (return_to_play_side_exception&) {
|
||||
if (!is_ok()) { DBG_AI_ACTIONS << "Return value of AI ACTION was not checked. This may cause bugs! " << std::endl; } //Demotes to DBG "unchecked result" warning
|
||||
throw;
|
||||
}
|
||||
|
@ -102,15 +102,6 @@ void action_result::execute()
|
|||
if (is_success()){
|
||||
check_after();
|
||||
}
|
||||
if(resources::controller->is_end_turn()) {
|
||||
throw ai_end_turn_exception();
|
||||
}
|
||||
|
||||
if(playsingle_controller* psc = dynamic_cast<playsingle_controller*>(resources::controller)) {
|
||||
if(psc->get_player_type_changed()) {
|
||||
throw restart_turn_exception();
|
||||
}
|
||||
}
|
||||
is_execution_ = false;
|
||||
}
|
||||
|
||||
|
@ -302,6 +293,7 @@ void attack_result::do_execute()
|
|||
set_scontext_synced sync;
|
||||
attack_unit_and_advance(attacker_loc_, defender_loc_, attacker_weapon, defender_weapon, true, advancements_);
|
||||
resources::controller->check_victory();
|
||||
resources::controller->maybe_throw_return_to_play_side();
|
||||
sync.do_final_checkup();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -788,18 +788,12 @@ void manager::play_turn( side_number side ){
|
|||
num_interact_ = 0;
|
||||
const int turn_start_time = SDL_GetTicks();
|
||||
/*hack. @todo 1.9 rework via extended event system*/
|
||||
try {
|
||||
get_ai_info().recent_attacks.clear();
|
||||
interface& ai_obj = get_active_ai_for_side(side);
|
||||
resources::game_events->pump().fire("ai turn");
|
||||
raise_turn_started();
|
||||
ai_obj.new_turn();
|
||||
ai_obj.play_turn();
|
||||
}
|
||||
catch (const ai_end_turn_exception&) {
|
||||
}
|
||||
catch(const restart_turn_exception&) {
|
||||
}
|
||||
get_ai_info().recent_attacks.clear();
|
||||
interface& ai_obj = get_active_ai_for_side(side);
|
||||
resources::game_events->pump().fire("ai turn");
|
||||
raise_turn_started();
|
||||
ai_obj.new_turn();
|
||||
ai_obj.play_turn();
|
||||
const int turn_end_time= SDL_GetTicks();
|
||||
DBG_AI_MANAGER << "side " << side << ": number of user interactions: "<<num_interact_<<std::endl;
|
||||
DBG_AI_MANAGER << "side " << side << ": total turn time: "<<turn_end_time - turn_start_time << " ms "<< std::endl;
|
||||
|
|
|
@ -162,7 +162,7 @@ gui::dialog_button_action::RESULT delete_recall_unit::button_pressed(int menu_se
|
|||
assert(dismissed_unit);
|
||||
|
||||
// Record the dismissal, then delete the unit.
|
||||
synced_context::run_in_synced_context("disband", replay_helper::get_disband(dismissed_unit->id()));
|
||||
synced_context::run_and_throw("disband", replay_helper::get_disband(dismissed_unit->id()));
|
||||
//recorder.add_disband(dismissed_unit->id());
|
||||
//recall_list.erase(dismissed_unit);
|
||||
|
||||
|
|
|
@ -40,74 +40,22 @@ MAKE_ENUM(LEVEL_RESULT,
|
|||
MAKE_ENUM_STREAM_OPS1(LEVEL_RESULT)
|
||||
|
||||
/**
|
||||
* Exception used to escape form the ai code in case of [end_turn].
|
||||
* Exception used to escape form the ai or ui code to playsingle_controller::play_side.
|
||||
* Never thrown during replays.
|
||||
*/
|
||||
class ai_end_turn_exception
|
||||
: public tlua_jailbreak_exception, public std::exception
|
||||
class return_to_play_side_exception : public tlua_jailbreak_exception, public std::exception
|
||||
{
|
||||
public:
|
||||
|
||||
ai_end_turn_exception()
|
||||
return_to_play_side_exception()
|
||||
: tlua_jailbreak_exception()
|
||||
, std::exception()
|
||||
{
|
||||
}
|
||||
const char * what() const throw() { return "ai_end_turn_exception"; }
|
||||
const char * what() const throw() { return "return_to_play_side_exception"; }
|
||||
private:
|
||||
|
||||
IMPLEMENT_LUA_JAILBREAK_EXCEPTION(ai_end_turn_exception)
|
||||
};
|
||||
|
||||
/**
|
||||
* Exception used to signal the end of a player turn.
|
||||
*/
|
||||
class restart_turn_exception
|
||||
: public tlua_jailbreak_exception, public std::exception
|
||||
{
|
||||
public:
|
||||
|
||||
restart_turn_exception()
|
||||
: tlua_jailbreak_exception()
|
||||
, std::exception()
|
||||
{
|
||||
}
|
||||
const char * what() const throw() { return "restart_turn_exception"; }
|
||||
|
||||
private:
|
||||
|
||||
IMPLEMENT_LUA_JAILBREAK_EXCEPTION(restart_turn_exception)
|
||||
};
|
||||
|
||||
/**
|
||||
* Struct used to transmit info caught from an end_turn_exception.
|
||||
*/
|
||||
struct end_level_struct
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* Exception used to signal the end of a scenario.
|
||||
*/
|
||||
class end_level_exception
|
||||
: public tlua_jailbreak_exception
|
||||
, public std::exception
|
||||
{
|
||||
public:
|
||||
|
||||
end_level_exception()
|
||||
: tlua_jailbreak_exception()
|
||||
, std::exception()
|
||||
{
|
||||
}
|
||||
|
||||
end_level_struct to_struct() {
|
||||
return end_level_struct();
|
||||
}
|
||||
|
||||
const char * what() const throw() { return "end_level_exception"; }
|
||||
private:
|
||||
|
||||
IMPLEMENT_LUA_JAILBREAK_EXCEPTION(end_level_exception)
|
||||
IMPLEMENT_LUA_JAILBREAK_EXCEPTION(return_to_play_side_exception)
|
||||
};
|
||||
|
||||
class quit_game_exception
|
||||
|
@ -125,48 +73,6 @@ public:
|
|||
private:
|
||||
IMPLEMENT_LUA_JAILBREAK_EXCEPTION(quit_game_exception)
|
||||
};
|
||||
/**
|
||||
* The two end_*_exceptions are caught and transformed to this signaling object
|
||||
*/
|
||||
typedef boost::optional<end_level_struct> possible_end_play_signal;
|
||||
|
||||
#define HANDLE_END_PLAY_SIGNAL( X )\
|
||||
do\
|
||||
{\
|
||||
try {\
|
||||
X;\
|
||||
} catch (end_level_exception & e) {\
|
||||
return possible_end_play_signal(e.to_struct());\
|
||||
}\
|
||||
}\
|
||||
while(0)
|
||||
|
||||
|
||||
|
||||
#define PROPOGATE_END_PLAY_SIGNAL( X )\
|
||||
do\
|
||||
{\
|
||||
possible_end_play_signal temp;\
|
||||
temp = X;\
|
||||
if (temp) {\
|
||||
return temp;\
|
||||
}\
|
||||
}\
|
||||
while(0)
|
||||
|
||||
|
||||
|
||||
#define HANDLE_AND_PROPOGATE_END_PLAY_SIGNAL( X )\
|
||||
do\
|
||||
{\
|
||||
possible_end_play_signal temp;\
|
||||
HANDLE_END_PLAY_SIGNAL( temp = X );\
|
||||
if (temp) {\
|
||||
return temp;\
|
||||
}\
|
||||
}\
|
||||
while(0)
|
||||
|
||||
|
||||
/**
|
||||
* The non-persistent part of end_level_data
|
||||
|
|
|
@ -208,7 +208,7 @@ void wml_menu_item::fire_event(const map_location & event_hex, const game_data &
|
|||
// note that there coudn't be a user choice during the last "select" event because it didn't run in a synced context.
|
||||
if ( needs_select_ && last_select.valid() )
|
||||
{
|
||||
synced_context::run_in_synced_context("fire_event", replay_helper::get_event(event_name_, event_hex, &last_select));
|
||||
synced_context::run_and_throw("fire_event", replay_helper::get_event(event_name_, event_hex, &last_select));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -153,7 +153,7 @@ LEVEL_RESULT play_replay(display& disp, saved_game& gamestate, const config& gam
|
|||
gui2::show_error_message(disp.video(), _("The game could not be loaded: ") + e.message);
|
||||
}
|
||||
|
||||
} catch(quit_game_exception& e) {
|
||||
} catch(quit_game_exception&) {
|
||||
LOG_NG << "The replay was aborted\n";
|
||||
return QUIT;
|
||||
} catch(game::game_error& e) {
|
||||
|
@ -207,11 +207,7 @@ static LEVEL_RESULT playsingle_scenario(const config& game_config,
|
|||
show_carryover_message(state_of_game, playcontroller, disp, end_level, res);
|
||||
if(!disp.video().faked())
|
||||
{
|
||||
try {
|
||||
playcontroller.maybe_linger();
|
||||
} catch(end_level_exception&) {
|
||||
return QUIT;
|
||||
}
|
||||
playcontroller.maybe_linger();
|
||||
}
|
||||
state_of_game.set_snapshot(playcontroller.to_config());
|
||||
return res;
|
||||
|
@ -249,11 +245,7 @@ static LEVEL_RESULT playmp_scenario(const config& game_config,
|
|||
}
|
||||
if(!disp.video().faked())
|
||||
{
|
||||
try {
|
||||
playcontroller.maybe_linger();
|
||||
} catch(end_level_exception&) {
|
||||
return QUIT;
|
||||
}
|
||||
playcontroller.maybe_linger();
|
||||
}
|
||||
playcontroller.update_savegame_snapshot();
|
||||
return res;
|
||||
|
@ -300,7 +292,7 @@ LEVEL_RESULT play_game(game_display& disp, saved_game& gamestate,
|
|||
} catch(game::load_game_failed& e) {
|
||||
gui2::show_error_message(disp.video(), _("The game could not be loaded: ") + e.message);
|
||||
return QUIT;
|
||||
} catch(quit_game_exception& e) {
|
||||
} catch(quit_game_exception&) {
|
||||
LOG_NG << "The game was aborted\n";
|
||||
return QUIT;
|
||||
} catch(game::game_error& e) {
|
||||
|
|
|
@ -79,12 +79,12 @@ public:
|
|||
virtual void ai_formula() {}
|
||||
virtual void clear_messages() {}
|
||||
virtual void change_language() {}
|
||||
virtual possible_end_play_signal play_replay() { return boost::none; }
|
||||
virtual void play_replay() { }
|
||||
virtual void reset_replay() {}
|
||||
virtual void stop_replay() {}
|
||||
virtual possible_end_play_signal replay_next_turn() { return boost::none; }
|
||||
virtual possible_end_play_signal replay_next_side() { return boost::none; }
|
||||
virtual possible_end_play_signal replay_next_move() { return boost::none; }
|
||||
virtual void replay_next_turn() { }
|
||||
virtual void replay_next_side() { }
|
||||
virtual void replay_next_move() { }
|
||||
virtual void replay_show_everything() {}
|
||||
virtual void replay_show_each() {}
|
||||
virtual void replay_show_team1() {}
|
||||
|
|
|
@ -42,13 +42,13 @@ public:
|
|||
{ return replay_controller_.reset_replay(); }
|
||||
virtual void stop_replay() OVERRIDE
|
||||
{ return replay_controller_.stop_replay(); }
|
||||
virtual possible_end_play_signal play_replay() OVERRIDE
|
||||
virtual void play_replay() OVERRIDE
|
||||
{ return replay_controller_.play_replay(); }
|
||||
virtual possible_end_play_signal replay_next_turn() OVERRIDE
|
||||
virtual void replay_next_turn() OVERRIDE
|
||||
{ return replay_controller_.replay_next_turn(); }
|
||||
virtual possible_end_play_signal replay_next_side() OVERRIDE
|
||||
virtual void replay_next_side() OVERRIDE
|
||||
{ return replay_controller_.replay_next_side(); }
|
||||
virtual possible_end_play_signal replay_next_move() OVERRIDE
|
||||
virtual void replay_next_move() OVERRIDE
|
||||
{ return replay_controller_.replay_next_move(); }
|
||||
virtual void replay_show_everything() OVERRIDE
|
||||
{ return replay_controller_.replay_show_everything(); }
|
||||
|
|
|
@ -663,7 +663,7 @@ bool menu_handler::do_recruit(const std::string &name, int side_num,
|
|||
|
||||
// Do the recruiting.
|
||||
|
||||
synced_context::run_in_synced_context("recruit", replay_helper::get_recruit(u_type->id(), loc, recruited_from));
|
||||
synced_context::run_and_throw("recruit", replay_helper::get_recruit(u_type->id(), loc, recruited_from));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -749,11 +749,10 @@ void menu_handler::recall(int side_num, const map_location &last_hex)
|
|||
}
|
||||
|
||||
if (!pc_.get_whiteboard() || !pc_.get_whiteboard()->save_recall(*recall_list_team->at(res), side_num, recall_location)) {
|
||||
bool success = synced_context::run_in_synced_context("recall",
|
||||
bool success = synced_context::run_and_throw("recall",
|
||||
replay_helper::get_recall(recall_list_team->at(res)->id(), recall_location, recall_from),
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
synced_context::ignore_error_function);
|
||||
|
||||
if(!success)
|
||||
|
@ -795,12 +794,12 @@ void menu_handler::toggle_shroud_updates(int side_num)
|
|||
if (!auto_shroud) update_shroud_now(side_num);
|
||||
|
||||
// Toggle the setting and record this.
|
||||
synced_context::run_in_synced_context("auto_shroud", replay_helper::get_auto_shroud(!auto_shroud));
|
||||
synced_context::run_and_throw("auto_shroud", replay_helper::get_auto_shroud(!auto_shroud));
|
||||
}
|
||||
|
||||
void menu_handler::update_shroud_now(int /* side_num */)
|
||||
{
|
||||
synced_context::run_in_synced_context("update_shroud", replay_helper::get_update_shroud());
|
||||
synced_context::run_and_throw("update_shroud", replay_helper::get_update_shroud());
|
||||
}
|
||||
|
||||
|
||||
|
@ -2971,7 +2970,7 @@ void console_handler::do_next_level()
|
|||
e.proceed_to_next_level = true;
|
||||
e.is_victory = true;
|
||||
menu_handler_.pc_.set_end_level_data(e);
|
||||
throw end_level_exception();
|
||||
throw return_to_play_side_exception();
|
||||
}
|
||||
|
||||
void console_handler::do_choose_level() {
|
||||
|
@ -3021,7 +3020,7 @@ void console_handler::do_choose_level() {
|
|||
e.proceed_to_next_level = true;
|
||||
e.is_victory = true;
|
||||
menu_handler_.pc_.set_end_level_data(e);
|
||||
throw end_level_exception();
|
||||
throw return_to_play_side_exception();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1156,7 +1156,7 @@ void mouse_handler::attack_enemy_(const map_location& att_loc
|
|||
|
||||
const tod_manager & tod_man = pc_.get_tod_manager_const();
|
||||
|
||||
synced_context::run_in_synced_context("attack", replay_helper::get_attack(attacker_loc, defender_loc, att.attack_num, def.attack_num,
|
||||
synced_context::run_and_throw("attack", replay_helper::get_attack(attacker_loc, defender_loc, att.attack_num, def.attack_num,
|
||||
attacker->type_id(), defender->type_id(), att.level,
|
||||
def.level, tod_man.turn(), tod_man.get_time_of_day()));
|
||||
}
|
||||
|
|
|
@ -300,7 +300,6 @@ void play_controller::fire_prestart()
|
|||
update_locker lock_display(gui_->video());
|
||||
gamestate_.gamedata_.set_phase(game_data::PRESTART);
|
||||
pump().fire("prestart");
|
||||
check_end_level();
|
||||
// prestart event may modify start turn with WML, reflect any changes.
|
||||
start_turn_ = turn();
|
||||
gamestate_.gamedata_.get_variable("turn_number") = int(start_turn_);
|
||||
|
@ -310,11 +309,10 @@ void play_controller::fire_start()
|
|||
{
|
||||
gamestate_.gamedata_.set_phase(game_data::START);
|
||||
pump().fire("start");
|
||||
check_end_level();
|
||||
// start event may modify start turn with WML, reflect any changes.
|
||||
start_turn_ = turn();
|
||||
gamestate_.gamedata_.get_variable("turn_number") = int(start_turn_);
|
||||
|
||||
check_objectives();
|
||||
// prestart and start events may modify the initial gold amount,
|
||||
// reflect any changes.
|
||||
BOOST_FOREACH(team& tm, gamestate_.board_.teams_)
|
||||
|
@ -867,9 +865,10 @@ void play_controller::check_victory()
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
check_end_level();
|
||||
|
||||
check_objectives();
|
||||
if (is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
bool continue_level, found_player, found_network_player, invalidate_all;
|
||||
std::set<unsigned> not_defeated;
|
||||
|
||||
|
@ -885,7 +884,10 @@ void play_controller::check_victory()
|
|||
|
||||
if (found_player || found_network_player) {
|
||||
pump().fire("enemies defeated");
|
||||
check_end_level();
|
||||
check_objectives();
|
||||
if (is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DBG_EE << "victory_when_enemies_defeated: " << victory_when_enemies_defeated_ << std::endl;
|
||||
|
@ -914,7 +916,6 @@ void play_controller::check_victory()
|
|||
el_data.proceed_to_next_level = found_player || found_network_player;
|
||||
el_data.is_victory = found_player;
|
||||
set_end_level_data(el_data);
|
||||
throw end_level_exception();
|
||||
}
|
||||
|
||||
void play_controller::process_oos(const std::string& msg) const
|
||||
|
@ -927,7 +928,7 @@ void play_controller::process_oos(const std::string& msg) const
|
|||
|
||||
update_savegame_snapshot();
|
||||
savegame::oos_savegame save(saved_game_, *gui_);
|
||||
save.save_game_interactive(gui_->video(), message.str(), gui::YES_NO); // can throw end_level_exception
|
||||
save.save_game_interactive(gui_->video(), message.str(), gui::YES_NO); // can throw quit_game_exception
|
||||
}
|
||||
|
||||
void play_controller::update_gui_to_player(const int team_index, const bool observe)
|
||||
|
@ -988,3 +989,18 @@ bool play_controller::is_browsing() const
|
|||
|| !init_side_done_
|
||||
|| this->gamestate_.gamedata_.phase() != game_data::PLAY;
|
||||
}
|
||||
|
||||
void play_controller::play_slice_catch()
|
||||
{
|
||||
if(should_return_to_play_side()) {
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
play_slice();
|
||||
}
|
||||
catch(const return_to_play_side_exception&)
|
||||
{
|
||||
assert(should_return_to_play_side());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,12 +111,12 @@ public:
|
|||
void init_side_end();
|
||||
|
||||
virtual void force_end_turn() = 0;
|
||||
virtual void check_end_level() = 0;
|
||||
virtual void check_objectives() = 0;
|
||||
|
||||
virtual void on_not_observer() = 0;
|
||||
/**
|
||||
* Asks the user whether to continue on an OOS error.
|
||||
* @throw end_level_exception If the user wants to abort.
|
||||
* @throw quit_game_exception If the user wants to abort.
|
||||
*/
|
||||
virtual void process_oos(const std::string& msg) const;
|
||||
|
||||
|
@ -161,7 +161,7 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a side has won, and throws an end_level_exception.
|
||||
* Checks to see if a side has won.
|
||||
* Will also remove control of villages from sides with dead leaders.
|
||||
*/
|
||||
void check_victory();
|
||||
|
@ -209,8 +209,13 @@ public:
|
|||
bool get_disallow_recall()
|
||||
{ return level_["disallow_recall"].to_bool(); }
|
||||
void update_savegame_snapshot() const;
|
||||
protected:
|
||||
virtual bool should_return_to_play_side()
|
||||
{ return is_regular_game_end(); }
|
||||
void maybe_throw_return_to_play_side()
|
||||
{ if(should_return_to_play_side()) { throw return_to_play_side_exception(); } }
|
||||
|
||||
protected:
|
||||
void play_slice_catch();
|
||||
game_display& get_display();
|
||||
bool have_keyboard_focus();
|
||||
void process_focus_keydown_event(const SDL_Event& event);
|
||||
|
|
|
@ -86,7 +86,7 @@ void playmp_controller::stop_network(){
|
|||
LOG_NG << "network processing stopped";
|
||||
}
|
||||
|
||||
possible_end_play_signal playmp_controller::play_side()
|
||||
void playmp_controller::play_side()
|
||||
{
|
||||
mp_ui_alerts::turn_changed(current_team().current_player());
|
||||
// Proceed with the parent function.
|
||||
|
@ -105,80 +105,79 @@ void playmp_controller::remove_blindfold() {
|
|||
}
|
||||
}
|
||||
|
||||
possible_end_play_signal playmp_controller::play_human_turn()
|
||||
void playmp_controller::play_linger_turn()
|
||||
{
|
||||
if (is_host()) {
|
||||
end_turn_enable(true);
|
||||
}
|
||||
|
||||
while(!end_turn_) {
|
||||
config cfg;
|
||||
if(network_reader_.read(cfg)) {
|
||||
if(turn_data_.process_network_data(cfg) == turn_info::PROCESS_END_LINGER)
|
||||
{
|
||||
end_turn();
|
||||
}
|
||||
}
|
||||
play_slice();
|
||||
gui_->draw();
|
||||
}
|
||||
}
|
||||
|
||||
void playmp_controller::play_human_turn()
|
||||
{
|
||||
LOG_NG << "playmp::play_human_turn...\n";
|
||||
|
||||
assert(!linger_);
|
||||
remove_blindfold();
|
||||
boost::scoped_ptr<countdown_clock> timer;
|
||||
if(!linger_ && saved_game_.mp_settings().mp_countdown) {
|
||||
if(saved_game_.mp_settings().mp_countdown) {
|
||||
timer.reset(new countdown_clock(current_team()));
|
||||
}
|
||||
show_turn_dialog();
|
||||
if(undo_stack_->can_undo()) {
|
||||
// If we reload a networked mp game we cannot undo moved made before the save
|
||||
// Becasue other players already received them
|
||||
synced_context::run_in_synced_context("update_shroud", replay_helper::get_update_shroud());
|
||||
synced_context::run_and_store("update_shroud", replay_helper::get_update_shroud());
|
||||
undo_stack_->clear();
|
||||
}
|
||||
if (!preferences::disable_auto_moves()) {
|
||||
HANDLE_END_PLAY_SIGNAL(execute_gotos());
|
||||
execute_gotos();
|
||||
}
|
||||
|
||||
if (!linger_ || is_host()) {
|
||||
end_turn_enable(true);
|
||||
}
|
||||
while(!end_turn_ && !player_type_changed_) {
|
||||
end_turn_enable(true);
|
||||
while(!should_return_to_play_side()) {
|
||||
try {
|
||||
config cfg;
|
||||
|
||||
if(network_reader_.read(cfg)) {
|
||||
turn_info::PROCESS_DATA_RESULT res;
|
||||
HANDLE_END_PLAY_SIGNAL( res = turn_data_.process_network_data(cfg) );
|
||||
if (res == turn_info::PROCESS_RESTART_TURN)
|
||||
process_network_data();
|
||||
if (player_type_changed_)
|
||||
{
|
||||
// Clean undo stack if turn has to be restarted (losing control)
|
||||
if ( undo_stack_->can_undo() )
|
||||
{
|
||||
player_type_changed_ = true;
|
||||
// Clean undo stack if turn has to be restarted (losing control)
|
||||
if ( undo_stack_->can_undo() )
|
||||
{
|
||||
font::floating_label flabel(_("Undoing moves not yet transmitted to the server."));
|
||||
font::floating_label flabel(_("Undoing moves not yet transmitted to the server."));
|
||||
|
||||
SDL_Color color = {255,255,255,255};
|
||||
flabel.set_color(color);
|
||||
SDL_Rect rect = gui_->map_area();
|
||||
flabel.set_position(rect.w/2, rect.h/2);
|
||||
flabel.set_lifetime(150);
|
||||
flabel.set_clip_rect(rect);
|
||||
SDL_Color color = {255,255,255,255};
|
||||
flabel.set_color(color);
|
||||
SDL_Rect rect = gui_->map_area();
|
||||
flabel.set_position(rect.w/2, rect.h/2);
|
||||
flabel.set_lifetime(150);
|
||||
flabel.set_clip_rect(rect);
|
||||
|
||||
font::add_floating_label(flabel);
|
||||
}
|
||||
|
||||
while( undo_stack_->can_undo() )
|
||||
undo_stack_->undo();
|
||||
|
||||
return boost::none;
|
||||
}
|
||||
else if(res == turn_info::PROCESS_END_LINGER)
|
||||
{
|
||||
if(!linger_)
|
||||
replay::process_error("Received unexpected next_scenario during the game");
|
||||
else
|
||||
{
|
||||
//we end the turn immidiately to prevent receiving data of the next scenario while we are not playing it.
|
||||
end_turn();
|
||||
}
|
||||
font::add_floating_label(flabel);
|
||||
}
|
||||
|
||||
while( undo_stack_->can_undo() )
|
||||
undo_stack_->undo();
|
||||
|
||||
}
|
||||
|
||||
HANDLE_END_PLAY_SIGNAL( play_slice() );
|
||||
play_slice_catch();
|
||||
if(timer)
|
||||
{
|
||||
SDL_Delay(1);
|
||||
bool time_left = timer->update();
|
||||
if(!time_left)
|
||||
{
|
||||
//End the turn of there is no time left.
|
||||
return boost::none;
|
||||
end_turn_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -191,38 +190,22 @@ possible_end_play_signal playmp_controller::play_human_turn()
|
|||
|
||||
gui_->draw();
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
possible_end_play_signal playmp_controller::play_idle_loop()
|
||||
void playmp_controller::play_idle_loop()
|
||||
{
|
||||
LOG_NG << "playmp::play_human_turn...\n";
|
||||
|
||||
remove_blindfold();
|
||||
|
||||
while (!end_turn_ && !player_type_changed_)
|
||||
while (!should_return_to_play_side())
|
||||
{
|
||||
try
|
||||
{
|
||||
config cfg;
|
||||
if(network_reader_.read(cfg)) {
|
||||
turn_info::PROCESS_DATA_RESULT res;
|
||||
HANDLE_END_PLAY_SIGNAL( res = turn_data_.process_network_data(cfg) );
|
||||
|
||||
if (res == turn_info::PROCESS_RESTART_TURN)
|
||||
{
|
||||
player_type_changed_ = true;
|
||||
return boost::none;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE_END_PLAY_SIGNAL ( play_slice() );
|
||||
|
||||
if (!linger_) {
|
||||
process_network_data();
|
||||
play_slice_catch();
|
||||
SDL_Delay(1);
|
||||
}
|
||||
|
||||
gui_->draw();
|
||||
gui_->draw();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -231,7 +214,6 @@ possible_end_play_signal playmp_controller::play_idle_loop()
|
|||
}
|
||||
turn_data_.send_data();
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
void playmp_controller::set_end_scenario_button()
|
||||
|
@ -280,19 +262,13 @@ void playmp_controller::linger()
|
|||
player_number_ = first_player_;
|
||||
turn_data_.send_data();
|
||||
end_turn_ = false;
|
||||
play_human_turn();
|
||||
play_linger_turn();
|
||||
after_human_turn();
|
||||
LOG_NG << "finished human turn" << std::endl;
|
||||
} catch (game::load_game_exception&) {
|
||||
LOG_NG << "caught load-game-exception" << std::endl;
|
||||
// this should not happen, the option to load a game is disabled
|
||||
throw;
|
||||
} catch (end_level_exception&) {
|
||||
// thrown if the host ends the scenario and let us advance
|
||||
// to the next level
|
||||
LOG_NG << "caught end-level-exception" << std::endl;
|
||||
reset_end_scenario_button();
|
||||
throw;
|
||||
} catch (network::error&) {
|
||||
LOG_NG << "caught network-error-exception" << std::endl;
|
||||
quit = false;
|
||||
|
@ -327,7 +303,7 @@ void playmp_controller::wait_for_upload()
|
|||
throw_quit_game_exception();
|
||||
}
|
||||
|
||||
} catch(const end_level_exception&) {
|
||||
} catch(const quit_game_exception&) {
|
||||
network_reader_.set_source(playturn_network_adapter::read_network);
|
||||
turn_data_.send_data();
|
||||
throw;
|
||||
|
@ -362,48 +338,22 @@ void playmp_controller::finish_side_turn(){
|
|||
play_controller::finish_side_turn();
|
||||
}
|
||||
|
||||
possible_end_play_signal playmp_controller::play_network_turn(){
|
||||
void playmp_controller::play_network_turn(){
|
||||
LOG_NG << "is networked...\n";
|
||||
|
||||
end_turn_enable(false);
|
||||
turn_data_.send_data();
|
||||
|
||||
for(;;) {
|
||||
|
||||
if (!network_processing_stopped_){
|
||||
config cfg;
|
||||
if(network_reader_.read(cfg)) {
|
||||
if (replay_last_turn_ <= turn()){
|
||||
skip_replay_ = false;
|
||||
}
|
||||
turn_info::PROCESS_DATA_RESULT result;
|
||||
HANDLE_END_PLAY_SIGNAL ( result = turn_data_.process_network_data(cfg) );
|
||||
if(player_type_changed_ == true)
|
||||
{
|
||||
//we received a player change/quit during waiting in get_user_choice/synced_context::pull_remote_user_input
|
||||
return boost::none;
|
||||
}
|
||||
if (result == turn_info::PROCESS_RESTART_TURN) {
|
||||
player_type_changed_ = true;
|
||||
return boost::none;
|
||||
} else if (result == turn_info::PROCESS_END_TURN) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
we might have data left in replay that we recieved during prestart events. (or maybe other events.)
|
||||
*/
|
||||
else if(!recorder.at_end())
|
||||
{
|
||||
if(do_replay() == REPLAY_FOUND_END_TURN)
|
||||
{
|
||||
break;
|
||||
}
|
||||
while(!should_return_to_play_side())
|
||||
{
|
||||
if (!network_processing_stopped_) {
|
||||
process_network_data();
|
||||
if (replay_last_turn_ <= turn()) {
|
||||
skip_replay_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE_END_PLAY_SIGNAL( play_slice() );
|
||||
|
||||
play_slice_catch();
|
||||
if (!network_processing_stopped_){
|
||||
turn_data_.send_data();
|
||||
}
|
||||
|
@ -412,7 +362,6 @@ possible_end_play_signal playmp_controller::play_network_turn(){
|
|||
}
|
||||
|
||||
LOG_NG << "finished networked...\n";
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
|
||||
|
@ -498,3 +447,30 @@ void playmp_controller::send_user_choice()
|
|||
{
|
||||
turn_data_.send_data();
|
||||
}
|
||||
|
||||
void playmp_controller::process_network_data()
|
||||
{
|
||||
if(should_return_to_play_side()) {
|
||||
return;
|
||||
}
|
||||
turn_info::PROCESS_DATA_RESULT res = turn_info::PROCESS_CONTINUE;
|
||||
config cfg;
|
||||
if(!recorder.at_end()) {
|
||||
res = turn_info::replay_to_process_data_result(do_replay());
|
||||
}
|
||||
else if(network_reader_.read(cfg)) {
|
||||
res = turn_data_.process_network_data(cfg);
|
||||
}
|
||||
|
||||
if (res == turn_info::PROCESS_RESTART_TURN) {
|
||||
player_type_changed_ = true;
|
||||
}
|
||||
else if (res == turn_info::PROCESS_END_TURN) {
|
||||
end_turn_ = true;
|
||||
}
|
||||
else if (res == turn_info::PROCESS_END_LEVEL) {
|
||||
}
|
||||
else if (res == turn_info::PROCESS_END_LINGER) {
|
||||
replay::process_error("Received unexpected next_scenario during the game");
|
||||
}
|
||||
}
|
|
@ -46,13 +46,14 @@ protected:
|
|||
void start_network();
|
||||
void stop_network();
|
||||
|
||||
virtual possible_end_play_signal play_side();
|
||||
virtual possible_end_play_signal play_human_turn();
|
||||
virtual void play_side();
|
||||
virtual void play_human_turn();
|
||||
virtual void play_linger_turn();
|
||||
virtual void after_human_turn();
|
||||
virtual void finish_side_turn();
|
||||
virtual possible_end_play_signal play_network_turn();
|
||||
virtual void play_network_turn();
|
||||
virtual void do_idle_notification();
|
||||
virtual possible_end_play_signal play_idle_loop();
|
||||
virtual void play_idle_loop();
|
||||
|
||||
void linger();
|
||||
/** Wait for the host to upload the next scenario. */
|
||||
|
@ -67,6 +68,7 @@ protected:
|
|||
private:
|
||||
void set_end_scenario_button();
|
||||
void reset_end_scenario_button();
|
||||
void process_network_data();
|
||||
static unsigned int replay_last_turn_;
|
||||
};
|
||||
|
||||
|
|
|
@ -205,12 +205,8 @@ void playsingle_controller::play_scenario_init() {
|
|||
saved_game_.replay_start() = to_config();
|
||||
}
|
||||
|
||||
try {
|
||||
fire_preload();
|
||||
} catch (end_level_exception) {
|
||||
return;
|
||||
}
|
||||
|
||||
fire_preload();
|
||||
|
||||
assert(recorder.at_end());
|
||||
|
||||
if(!loading_game_ )
|
||||
|
@ -221,20 +217,17 @@ void playsingle_controller::play_scenario_init() {
|
|||
//we can only use a set_scontext_synced with a non empty recorder.
|
||||
set_scontext_synced sync;
|
||||
|
||||
try {
|
||||
fire_prestart();
|
||||
} catch (end_level_exception) {
|
||||
fire_prestart();
|
||||
if (is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
init_gui();
|
||||
LOG_NG << "first_time..." << (is_skipping_replay() ? "skipping" : "no skip") << "\n";
|
||||
|
||||
events::raise_draw_event();
|
||||
try {
|
||||
fire_start();
|
||||
} catch (end_level_exception) {
|
||||
fire_start();
|
||||
if (is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
sync.do_final_checkup();
|
||||
|
@ -279,9 +272,8 @@ void playsingle_controller::play_scenario_main_loop() {
|
|||
ERR_NG << "Playing game with 0 teams." << std::endl;
|
||||
}
|
||||
for(; ; first_player_ = 1) {
|
||||
possible_end_play_signal signal = play_turn();
|
||||
|
||||
if (signal) {
|
||||
play_turn();
|
||||
if (is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -427,7 +419,7 @@ LEVEL_RESULT playsingle_controller::play_scenario(
|
|||
return QUIT;
|
||||
}
|
||||
|
||||
possible_end_play_signal playsingle_controller::play_turn()
|
||||
void playsingle_controller::play_turn()
|
||||
{
|
||||
whiteboard_manager_->on_gamestate_change();
|
||||
gui_->new_turn();
|
||||
|
@ -445,7 +437,6 @@ possible_end_play_signal playsingle_controller::play_turn()
|
|||
// If a side is empty skip over it.
|
||||
if (current_team().is_empty()) continue;
|
||||
|
||||
possible_end_play_signal signal;
|
||||
{
|
||||
save_blocker blocker;
|
||||
init_side_begin(false);
|
||||
|
@ -456,9 +447,14 @@ possible_end_play_signal playsingle_controller::play_turn()
|
|||
}
|
||||
|
||||
ai_testing::log_turn_start(player_number_);
|
||||
PROPOGATE_END_PLAY_SIGNAL ( play_side() );
|
||||
HANDLE_END_PLAY_SIGNAL(finish_side_turn());
|
||||
|
||||
play_side();
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
finish_side_turn();
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
if(non_interactive()) {
|
||||
LOG_AIT << " Player " << player_number_ << ": " <<
|
||||
current_team().villages().size() << " Villages" <<
|
||||
|
@ -475,30 +471,28 @@ possible_end_play_signal playsingle_controller::play_turn()
|
|||
finish_turn();
|
||||
|
||||
// Time has run out
|
||||
PROPOGATE_END_PLAY_SIGNAL ( check_time_over() );
|
||||
return boost::none;
|
||||
check_time_over();
|
||||
}
|
||||
|
||||
possible_end_play_signal playsingle_controller::play_idle_loop()
|
||||
void playsingle_controller::play_idle_loop()
|
||||
{
|
||||
while(!end_turn_ && !player_type_changed_) {
|
||||
HANDLE_END_PLAY_SIGNAL( play_slice() );
|
||||
while(!should_return_to_play_side()) {
|
||||
play_slice_catch();
|
||||
gui_->draw();
|
||||
SDL_Delay(10);
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
possible_end_play_signal playsingle_controller::play_side()
|
||||
void playsingle_controller::play_side()
|
||||
{
|
||||
//check for team-specific items in the scenario
|
||||
gui_->parse_team_overlays();
|
||||
|
||||
try {
|
||||
maybe_do_init_side();
|
||||
} catch (end_level_exception & e) {
|
||||
return possible_end_play_signal(e.to_struct());
|
||||
maybe_do_init_side();
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//flag used when we fallback from ai and give temporarily control to human
|
||||
bool temporary_human = false;
|
||||
do {
|
||||
|
@ -525,8 +519,9 @@ possible_end_play_signal playsingle_controller::play_side()
|
|||
{
|
||||
before_human_turn();
|
||||
if (!end_turn_) {
|
||||
if(possible_end_play_signal signal = play_idle_loop()) {
|
||||
return signal;
|
||||
play_human_turn();
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -542,8 +537,9 @@ possible_end_play_signal playsingle_controller::play_side()
|
|||
// Give control to a human for this turn.
|
||||
player_type_changed_ = true;
|
||||
temporary_human = true;
|
||||
} catch (end_level_exception &e) {
|
||||
return possible_end_play_signal(e.to_struct());
|
||||
}
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
if(!player_type_changed_)
|
||||
{
|
||||
|
@ -551,14 +547,18 @@ possible_end_play_signal playsingle_controller::play_side()
|
|||
}
|
||||
|
||||
} else if(current_team().is_network()) {
|
||||
PROPOGATE_END_PLAY_SIGNAL( play_network_turn() );
|
||||
play_network_turn();
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
} else if(current_team().is_local_human() && current_team().is_idle()) {
|
||||
end_turn_enable(false);
|
||||
do_idle_notification();
|
||||
before_human_turn();
|
||||
if (!end_turn_) {
|
||||
if(possible_end_play_signal signal = play_idle_loop()) {
|
||||
return signal;
|
||||
play_idle_loop();
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -570,7 +570,6 @@ possible_end_play_signal playsingle_controller::play_side()
|
|||
// Keep looping if the type of a team (human/ai/networked)
|
||||
// has changed mid-turn
|
||||
skip_next_turn_ = false;
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
void playsingle_controller::before_human_turn()
|
||||
|
@ -607,24 +606,34 @@ void playsingle_controller::show_turn_dialog(){
|
|||
}
|
||||
}
|
||||
|
||||
void playsingle_controller::execute_gotos(){
|
||||
menu_handler_.execute_gotos(mouse_handler_, player_number_);
|
||||
void playsingle_controller::execute_gotos()
|
||||
{
|
||||
if(should_return_to_play_side())
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
menu_handler_.execute_gotos(mouse_handler_, player_number_);
|
||||
}
|
||||
catch (const return_to_play_side_exception&)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
possible_end_play_signal playsingle_controller::play_human_turn() {
|
||||
void playsingle_controller::play_human_turn() {
|
||||
show_turn_dialog();
|
||||
|
||||
if (!preferences::disable_auto_moves()) {
|
||||
HANDLE_END_PLAY_SIGNAL(execute_gotos());
|
||||
execute_gotos();
|
||||
}
|
||||
|
||||
end_turn_enable(true);
|
||||
while(!end_turn_ && !player_type_changed_) {
|
||||
HANDLE_END_PLAY_SIGNAL( play_slice() );
|
||||
while(!should_return_to_play_side()) {
|
||||
play_slice_catch();
|
||||
gui_->draw();
|
||||
}
|
||||
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
void playsingle_controller::linger()
|
||||
|
@ -707,13 +716,17 @@ void playsingle_controller::play_ai_turn()
|
|||
if ( !cur_team.auto_shroud_updates() ) {
|
||||
// We just took control, so the undo stack is empty. We still need
|
||||
// to record this change for the replay though.
|
||||
synced_context::run_in_synced_context("auto_shroud", replay_helper::get_auto_shroud(true));
|
||||
synced_context::run_and_store("auto_shroud", replay_helper::get_auto_shroud(true));
|
||||
}
|
||||
undo_stack_->clear();
|
||||
|
||||
turn_data_.send_data();
|
||||
try {
|
||||
ai::manager::play_turn(player_number_);
|
||||
try {
|
||||
ai::manager::play_turn(player_number_);
|
||||
}
|
||||
catch (return_to_play_side_exception&) {
|
||||
}
|
||||
}
|
||||
catch(...) {
|
||||
turn_data_.sync_network();
|
||||
|
@ -742,11 +755,10 @@ void playsingle_controller::do_idle_notification()
|
|||
/**
|
||||
* Will handle networked turns in descendent classes.
|
||||
*/
|
||||
possible_end_play_signal playsingle_controller::play_network_turn()
|
||||
void playsingle_controller::play_network_turn()
|
||||
{
|
||||
// There should be no networked sides in single-player.
|
||||
ERR_NG << "Networked team encountered by playsingle_controller." << std::endl;
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
|
||||
|
@ -756,7 +768,7 @@ void playsingle_controller::handle_generic_event(const std::string& name){
|
|||
}
|
||||
}
|
||||
|
||||
possible_end_play_signal playsingle_controller::check_time_over(){
|
||||
void playsingle_controller::check_time_over(){
|
||||
bool time_left = gamestate_.tod_manager_.next_turn(gamestate_.gamedata_);
|
||||
it_is_a_new_turn_ = true;
|
||||
if(!time_left) {
|
||||
|
@ -766,7 +778,7 @@ possible_end_play_signal playsingle_controller::check_time_over(){
|
|||
LOG_NG << "done firing time over event...\n";
|
||||
//if turns are added while handling 'time over' event
|
||||
if (gamestate_.tod_manager_.is_time_left()) {
|
||||
return boost::none;
|
||||
return;
|
||||
}
|
||||
|
||||
if(non_interactive()) {
|
||||
|
@ -774,14 +786,15 @@ possible_end_play_signal playsingle_controller::check_time_over(){
|
|||
ai_testing::log_draw();
|
||||
}
|
||||
|
||||
HANDLE_END_PLAY_SIGNAL( check_victory() );
|
||||
check_victory();
|
||||
if (is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
end_level_data e;
|
||||
e.proceed_to_next_level = false;
|
||||
e.is_victory = false;
|
||||
set_end_level_data(e);
|
||||
return possible_end_play_signal (end_level_struct());
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
void playsingle_controller::end_turn(){
|
||||
|
@ -797,18 +810,16 @@ void playsingle_controller::force_end_turn(){
|
|||
end_turn_ = true;
|
||||
}
|
||||
|
||||
void playsingle_controller::check_end_level()
|
||||
void playsingle_controller::check_objectives()
|
||||
{
|
||||
if (!is_regular_game_end() || linger_)
|
||||
{
|
||||
const team &t = gamestate_.board_.teams()[gui_->viewing_team()];
|
||||
if (!is_browsing() && t.objectives_changed()) {
|
||||
dialogs::show_objectives(get_scenario_name().str(), t.objectives());
|
||||
t.reset_objectives_changed();
|
||||
}
|
||||
if (!is_regular_game_end() || linger_) {
|
||||
return;
|
||||
}
|
||||
throw end_level_exception();
|
||||
const team &t = gamestate_.board_.teams()[gui_->viewing_team()];
|
||||
if (!is_browsing() && t.objectives_changed()) {
|
||||
dialogs::show_objectives(get_scenario_name().str(), t.objectives());
|
||||
t.reset_objectives_changed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
|
||||
virtual void handle_generic_event(const std::string& name);
|
||||
|
||||
virtual void check_end_level();
|
||||
virtual void check_objectives();
|
||||
void report_victory(std::ostringstream &report, team& t, int finishing_bonus_per_turn,
|
||||
int turns_left, int finishing_bonus);
|
||||
virtual void on_not_observer() {}
|
||||
|
@ -54,21 +54,23 @@ public:
|
|||
|
||||
bool get_player_type_changed() const { return player_type_changed_; }
|
||||
void set_player_type_changed() { player_type_changed_ = true; }
|
||||
virtual bool should_return_to_play_side()
|
||||
{ return player_type_changed_ || end_turn_ || is_regular_game_end(); }
|
||||
protected:
|
||||
possible_end_play_signal play_turn();
|
||||
virtual possible_end_play_signal play_side();
|
||||
void play_turn();
|
||||
virtual void play_side();
|
||||
void before_human_turn();
|
||||
void show_turn_dialog();
|
||||
void execute_gotos();
|
||||
virtual possible_end_play_signal play_human_turn();
|
||||
virtual void play_human_turn();
|
||||
virtual void after_human_turn();
|
||||
void end_turn_enable(bool enable);
|
||||
void play_ai_turn();
|
||||
virtual possible_end_play_signal play_idle_loop();
|
||||
virtual void play_idle_loop();
|
||||
virtual void do_idle_notification();
|
||||
virtual possible_end_play_signal play_network_turn();
|
||||
virtual void play_network_turn();
|
||||
virtual void init_gui();
|
||||
possible_end_play_signal check_time_over();
|
||||
void check_time_over();
|
||||
void store_recalls();
|
||||
void store_gold(bool obs = false);
|
||||
|
||||
|
|
|
@ -413,6 +413,8 @@ turn_info::PROCESS_DATA_RESULT turn_info::replay_to_process_data_result(REPLAY_R
|
|||
return PROCESS_FOUND_DEPENDENT;
|
||||
case REPLAY_FOUND_END_TURN:
|
||||
return PROCESS_END_TURN;
|
||||
case REPLAY_FOUND_END_LEVEL:
|
||||
return PROCESS_END_LEVEL;
|
||||
default:
|
||||
assert(false);
|
||||
throw "found invalid REPLAY_RETURN";
|
||||
|
|
|
@ -42,7 +42,9 @@ public:
|
|||
/** When the host uploaded the next scenario this is returned. */
|
||||
PROCESS_END_LINGER,
|
||||
/** When we couldn't process the network data because we found a dependent command, this should only happen if we were called playmp_controller::from handle_generic_event -> sync_network*/
|
||||
PROCESS_FOUND_DEPENDENT
|
||||
PROCESS_FOUND_DEPENDENT,
|
||||
/** We foudn a player action in the replay that caused the game to end*/
|
||||
PROCESS_END_LEVEL
|
||||
};
|
||||
|
||||
PROCESS_DATA_RESULT sync_network();
|
||||
|
@ -60,10 +62,10 @@ public:
|
|||
|
||||
bool is_host() const { return is_host_; }
|
||||
void set_host(bool val) { is_host_ = val; }
|
||||
static PROCESS_DATA_RESULT replay_to_process_data_result(REPLAY_RETURN replayreturn);
|
||||
private:
|
||||
static void change_controller(int side, const std::string& controller);
|
||||
static void change_side_controller(int side, const std::string& player);
|
||||
static PROCESS_DATA_RESULT replay_to_process_data_result(REPLAY_RETURN replayreturn);
|
||||
PROCESS_DATA_RESULT handle_turn(const config& t);
|
||||
|
||||
void do_save();
|
||||
|
|
|
@ -210,7 +210,7 @@ void replay::process_error(const std::string& msg)
|
|||
{
|
||||
ERR_REPLAY << msg << std::flush;
|
||||
|
||||
resources::controller->process_oos(msg); // might throw end_level_exception(QUIT)
|
||||
resources::controller->process_oos(msg); // might throw quit_game_exception()
|
||||
}
|
||||
|
||||
void replay::add_unit_checksum(const map_location& loc,config& cfg)
|
||||
|
@ -853,7 +853,10 @@ REPLAY_RETURN do_replay_handle(bool one_move)
|
|||
/*
|
||||
we need to use the undo stack during replays in order to make delayed shroud updated work.
|
||||
*/
|
||||
synced_context::run_in_synced_context(commandname, data, true, !resources::controller->is_skipping_replay(), false,show_oos_error_error_function);
|
||||
synced_context::run(commandname, data, true, !resources::controller->is_skipping_replay(), show_oos_error_error_function);
|
||||
if(resources::controller->is_regular_game_end()) {
|
||||
return REPLAY_FOUND_END_LEVEL;
|
||||
}
|
||||
if (one_move) {
|
||||
return REPLAY_FOUND_END_MOVE;
|
||||
}
|
||||
|
|
|
@ -160,7 +160,8 @@ enum REPLAY_RETURN
|
|||
REPLAY_RETURN_AT_END,
|
||||
REPLAY_FOUND_DEPENDENT,
|
||||
REPLAY_FOUND_END_TURN,
|
||||
REPLAY_FOUND_END_MOVE
|
||||
REPLAY_FOUND_END_MOVE,
|
||||
REPLAY_FOUND_END_LEVEL
|
||||
};
|
||||
//replays up to one turn from the recorder object
|
||||
//returns true if it got to the end of the turn without data running out
|
||||
|
|
|
@ -52,7 +52,7 @@ static lg::log_domain log_replay("replay");
|
|||
#define LOG_REPLAY LOG_STREAM(info, log_replay)
|
||||
#define ERR_REPLAY LOG_STREAM(err, log_replay)
|
||||
|
||||
possible_end_play_signal play_replay_level_main_loop(replay_controller & replaycontroller, bool & is_unit_test);
|
||||
void play_replay_level_main_loop(replay_controller & replaycontroller, bool & is_unit_test);
|
||||
|
||||
LEVEL_RESULT play_replay_level(const config& game_config, const tdata_cache & tdata,
|
||||
CVideo& video, saved_game& state_of_game, bool is_unit_test)
|
||||
|
@ -65,42 +65,43 @@ LEVEL_RESULT play_replay_level(const config& game_config, const tdata_cache & td
|
|||
|
||||
const events::command_disabler disable_commands;
|
||||
|
||||
try {
|
||||
rc.reset(new replay_controller(state_of_game.get_replay_starting_pos(), state_of_game, ticks, game_config, tdata, video));
|
||||
} catch (end_level_exception&){
|
||||
//TODO: When can this happen?
|
||||
return QUIT;
|
||||
}
|
||||
rc.reset(new replay_controller(state_of_game.get_replay_starting_pos(), state_of_game, ticks, game_config, tdata, video));
|
||||
DBG_NG << "created objects... " << (SDL_GetTicks() - rc->get_ticks()) << std::endl;
|
||||
|
||||
//replay event-loop
|
||||
possible_end_play_signal signal = play_replay_level_main_loop(*rc, is_unit_test);
|
||||
|
||||
if (signal) {
|
||||
DBG_NG << "play_replay_level: end_level_exception" << std::endl;
|
||||
play_replay_level_main_loop(*rc, is_unit_test);
|
||||
if(rc->is_regular_game_end())
|
||||
{
|
||||
// return rc->get_end_level_data_const().is_victory ? VICTORY : DEFEAT;
|
||||
//The replay contained the whole scenario, returns VICTORY regardless of the original outcome.
|
||||
return VICTORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
//The replay was finished without reaching the scenario end.
|
||||
return QUIT;
|
||||
}
|
||||
|
||||
return VICTORY;
|
||||
}
|
||||
|
||||
possible_end_play_signal play_replay_level_main_loop(replay_controller & replaycontroller, bool & is_unit_test) {
|
||||
void play_replay_level_main_loop(replay_controller & replaycontroller, bool & is_unit_test) {
|
||||
if (is_unit_test) {
|
||||
return replaycontroller.try_run_to_completion();
|
||||
}
|
||||
|
||||
for (;;){
|
||||
HANDLE_END_PLAY_SIGNAL( replaycontroller.play_slice() );
|
||||
for (;;) {
|
||||
//Quits by quit_level_exception
|
||||
replaycontroller.play_slice();
|
||||
}
|
||||
}
|
||||
|
||||
possible_end_play_signal replay_controller::try_run_to_completion() {
|
||||
void replay_controller::try_run_to_completion() {
|
||||
for (;;) {
|
||||
HANDLE_END_PLAY_SIGNAL( play_slice() );
|
||||
play_slice();
|
||||
if (recorder.at_end()) {
|
||||
return boost::none;
|
||||
return;
|
||||
} else {
|
||||
if (!is_playing_) {
|
||||
PROPOGATE_END_PLAY_SIGNAL( play_replay() );
|
||||
play_replay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,31 +381,33 @@ void replay_controller::reset_replay()
|
|||
reset_replay_ui();
|
||||
}
|
||||
|
||||
void replay_controller::stop_replay(){
|
||||
void replay_controller::stop_replay()
|
||||
{
|
||||
is_playing_ = false;
|
||||
}
|
||||
|
||||
possible_end_play_signal replay_controller::replay_next_turn(){
|
||||
void replay_controller::replay_next_turn()
|
||||
{
|
||||
is_playing_ = true;
|
||||
replay_ui_playback_should_start();
|
||||
|
||||
PROPOGATE_END_PLAY_SIGNAL( play_turn() );
|
||||
play_turn();
|
||||
|
||||
if (!is_skipping_replay() || !is_playing_){
|
||||
gui_->scroll_to_leader(player_number_,game_display::ONSCREEN,false);
|
||||
}
|
||||
|
||||
replay_ui_playback_should_stop();
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
possible_end_play_signal replay_controller::replay_next_move_or_side(bool one_move){
|
||||
void replay_controller::replay_next_move_or_side(bool one_move)
|
||||
{
|
||||
is_playing_ = true;
|
||||
replay_ui_playback_should_start();
|
||||
|
||||
HANDLE_END_PLAY_SIGNAL( play_move_or_side(one_move) );
|
||||
play_move_or_side(one_move);
|
||||
while (current_team().is_empty()) {
|
||||
HANDLE_END_PLAY_SIGNAL( play_move_or_side(one_move) );
|
||||
play_move_or_side(one_move);
|
||||
}
|
||||
|
||||
if ( (!is_skipping_replay() || !is_playing_) && (last_replay_action == REPLAY_FOUND_END_TURN) ){
|
||||
|
@ -412,14 +415,15 @@ possible_end_play_signal replay_controller::replay_next_move_or_side(bool one_mo
|
|||
}
|
||||
|
||||
replay_ui_playback_should_stop();
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
possible_end_play_signal replay_controller::replay_next_side(){
|
||||
void replay_controller::replay_next_side()
|
||||
{
|
||||
return replay_next_move_or_side(false);
|
||||
}
|
||||
|
||||
possible_end_play_signal replay_controller::replay_next_move(){
|
||||
void replay_controller::replay_next_move()
|
||||
{
|
||||
return replay_next_move_or_side(true);
|
||||
}
|
||||
|
||||
|
@ -469,40 +473,36 @@ void replay_controller::replay_skip_animation(){
|
|||
}
|
||||
|
||||
//move all sides till stop/end
|
||||
possible_end_play_signal replay_controller::play_replay(){
|
||||
void replay_controller::play_replay()
|
||||
{
|
||||
|
||||
if (recorder.at_end()){
|
||||
//shouldn't actually happen
|
||||
return boost::none;
|
||||
if (recorder.at_end())
|
||||
{
|
||||
}
|
||||
|
||||
is_playing_ = true;
|
||||
replay_ui_playback_should_start();
|
||||
|
||||
possible_end_play_signal signal = play_replay_main_loop();
|
||||
|
||||
if(signal) {
|
||||
}
|
||||
play_replay_main_loop();
|
||||
|
||||
if (!is_playing_) {
|
||||
gui_->scroll_to_leader(player_number_,game_display::ONSCREEN,false);
|
||||
}
|
||||
|
||||
replay_ui_playback_should_stop();
|
||||
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
possible_end_play_signal replay_controller::play_replay_main_loop() {
|
||||
void replay_controller::play_replay_main_loop()
|
||||
{
|
||||
DBG_REPLAY << "starting main loop\n" << (SDL_GetTicks() - ticks_) << "\n";
|
||||
for(; !recorder.at_end() && is_playing_; first_player_ = 1) {
|
||||
PROPOGATE_END_PLAY_SIGNAL ( play_turn() );
|
||||
play_turn();
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
//make all sides move, then stop
|
||||
possible_end_play_signal replay_controller::play_turn(){
|
||||
void replay_controller::play_turn()
|
||||
{
|
||||
|
||||
LOG_REPLAY << "turn: " << current_turn_ << "\n";
|
||||
|
||||
|
@ -514,23 +514,22 @@ possible_end_play_signal replay_controller::play_turn(){
|
|||
|
||||
while ( (!last_team) && (!recorder.at_end()) && is_playing_ ){
|
||||
last_team = static_cast<size_t>(player_number_) == gamestate_.board_.teams().size();
|
||||
PROPOGATE_END_PLAY_SIGNAL( play_side() );
|
||||
HANDLE_END_PLAY_SIGNAL( play_slice() );
|
||||
play_side();
|
||||
play_slice();
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
|
||||
possible_end_play_signal replay_controller::play_side() {
|
||||
void replay_controller::play_side() {
|
||||
return play_move_or_side(false);
|
||||
}
|
||||
|
||||
possible_end_play_signal replay_controller::play_move() {
|
||||
void replay_controller::play_move() {
|
||||
return play_move_or_side(true);
|
||||
}
|
||||
|
||||
//make only one side move
|
||||
possible_end_play_signal replay_controller::play_move_or_side(bool one_move) {
|
||||
void replay_controller::play_move_or_side(bool one_move) {
|
||||
|
||||
DBG_REPLAY << "Status turn number: " << turn() << "\n";
|
||||
DBG_REPLAY << "Replay_Controller turn number: " << current_turn_ << "\n";
|
||||
|
@ -540,7 +539,6 @@ possible_end_play_signal replay_controller::play_move_or_side(bool one_move) {
|
|||
if (!current_team().is_empty()) {
|
||||
statistics::reset_turn_stats(current_team().save_id());
|
||||
|
||||
possible_end_play_signal signal = NULL;
|
||||
if (last_replay_action == REPLAY_FOUND_END_TURN) {
|
||||
play_controller::init_side_begin(true);
|
||||
}
|
||||
|
@ -549,18 +547,10 @@ possible_end_play_signal replay_controller::play_move_or_side(bool one_move) {
|
|||
// if have reached the end we don't want to execute finish_side_turn and finish_turn
|
||||
// because we might not have enough data to execute them (like advancements during turn_end for example)
|
||||
|
||||
try {
|
||||
last_replay_action = do_replay(one_move);
|
||||
if(last_replay_action != REPLAY_FOUND_END_TURN) {
|
||||
//We reached the end of the replay without finding an end turn tag.
|
||||
//REPLAY_FOUND_DEPENDENT here might indicate an OOS error
|
||||
return boost::none;
|
||||
}
|
||||
} catch(end_level_exception& e){
|
||||
//dont return to title screen if the game ended the normal way
|
||||
if (!is_regular_game_end()) {
|
||||
return possible_end_play_signal(e.to_struct());
|
||||
}
|
||||
last_replay_action = do_replay(one_move);
|
||||
if(last_replay_action != REPLAY_FOUND_END_TURN) {
|
||||
//We reached the end of the replay without finding an end turn tag.
|
||||
return;
|
||||
}
|
||||
|
||||
finish_side_turn();
|
||||
|
@ -589,11 +579,10 @@ possible_end_play_signal replay_controller::play_move_or_side(bool one_move) {
|
|||
|
||||
update_teams();
|
||||
update_gui();
|
||||
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
void replay_controller::update_teams(){
|
||||
void replay_controller::update_teams()
|
||||
{
|
||||
|
||||
int next_team = player_number_;
|
||||
if(static_cast<size_t>(next_team) > gamestate_.board_.teams().size()) {
|
||||
|
@ -610,7 +599,8 @@ void replay_controller::update_teams(){
|
|||
gui_->invalidate_all();
|
||||
}
|
||||
|
||||
void replay_controller::update_gui(){
|
||||
void replay_controller::update_gui()
|
||||
{
|
||||
(*gui_).recalculate_minimap();
|
||||
(*gui_).redraw_minimap();
|
||||
(*gui_).invalidate_all();
|
||||
|
@ -618,7 +608,8 @@ void replay_controller::update_gui(){
|
|||
(*gui_).draw();
|
||||
}
|
||||
|
||||
void replay_controller::handle_generic_event(const std::string& name){
|
||||
void replay_controller::handle_generic_event(const std::string& name)
|
||||
{
|
||||
|
||||
if( name == "completely_redrawn" ) {
|
||||
update_replay_ui();
|
||||
|
|
|
@ -32,13 +32,13 @@ public:
|
|||
const int ticks, const config& game_config, const tdata_cache & tdata, CVideo& video);
|
||||
virtual ~replay_controller();
|
||||
|
||||
possible_end_play_signal play_replay();
|
||||
void play_replay();
|
||||
void reset_replay();
|
||||
void stop_replay();
|
||||
possible_end_play_signal replay_next_move_or_side(bool one_move);
|
||||
possible_end_play_signal replay_next_turn();
|
||||
possible_end_play_signal replay_next_side();
|
||||
possible_end_play_signal replay_next_move();
|
||||
void replay_next_move_or_side(bool one_move);
|
||||
void replay_next_turn();
|
||||
void replay_next_side();
|
||||
void replay_next_move();
|
||||
void process_oos(const std::string& msg) const;
|
||||
void replay_show_everything();
|
||||
void replay_show_each();
|
||||
|
@ -46,10 +46,10 @@ public:
|
|||
void replay_skip_animation();
|
||||
|
||||
virtual void force_end_turn() {}
|
||||
virtual void check_end_level() {}
|
||||
virtual void check_objectives() {}
|
||||
virtual void on_not_observer() {}
|
||||
|
||||
possible_end_play_signal try_run_to_completion();
|
||||
void try_run_to_completion();
|
||||
|
||||
bool recorder_at_end();
|
||||
|
||||
|
@ -61,17 +61,17 @@ protected:
|
|||
|
||||
private:
|
||||
void init();
|
||||
possible_end_play_signal play_turn();
|
||||
possible_end_play_signal play_move_or_side(bool one_move = false);
|
||||
possible_end_play_signal play_side();
|
||||
possible_end_play_signal play_move();
|
||||
void play_turn();
|
||||
void play_move_or_side(bool one_move = false);
|
||||
void play_side();
|
||||
void play_move();
|
||||
void update_teams();
|
||||
void update_gui();
|
||||
void init_replay_display();
|
||||
void rebuild_replay_theme();
|
||||
void handle_generic_event(const std::string& /*name*/);
|
||||
|
||||
possible_end_play_signal play_replay_main_loop();
|
||||
void play_replay_main_loop();
|
||||
|
||||
void reset_replay_ui();
|
||||
void update_replay_ui();
|
||||
|
|
|
@ -54,23 +54,11 @@ synced_context::synced_state synced_context::state_ = synced_context::UNSYNCED;
|
|||
int synced_context::last_unit_id_ = 0;
|
||||
bool synced_context::is_simultaneously_ = false;
|
||||
|
||||
bool synced_context::run_in_synced_context(const std::string& commandname, const config& data, bool use_undo, bool show, bool store_in_replay, synced_command::error_handler_function error_handler)
|
||||
bool synced_context::run(const std::string& commandname, const config& data, bool use_undo, bool show, synced_command::error_handler_function error_handler)
|
||||
{
|
||||
DBG_REPLAY << "run_in_synced_context:" << commandname << "\n";
|
||||
|
||||
if(!recorder.at_end() && store_in_replay)
|
||||
{
|
||||
//Most likeley we are in a replay now.
|
||||
//We don't want to execute [do_command] & similar now
|
||||
WRN_REPLAY << "invalid run_in_synced_context call ignored" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(use_undo || (!resources::undo_stack->can_redo() && !resources::undo_stack->can_undo()));
|
||||
if(store_in_replay)
|
||||
{
|
||||
recorder.add_synced_command(commandname, data);
|
||||
}
|
||||
/*
|
||||
use this after recorder.add_synced_command
|
||||
because set_scontext_synced sets the checkup to the last added command
|
||||
|
@ -84,10 +72,8 @@ bool synced_context::run_in_synced_context(const std::string& commandname, const
|
|||
else
|
||||
{
|
||||
bool success = it->second(data, use_undo, show, error_handler);
|
||||
if(!success && store_in_replay)
|
||||
if(!success)
|
||||
{
|
||||
//remove it from replay if we weren't sucessful.
|
||||
recorder.undo();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -100,6 +86,27 @@ bool synced_context::run_in_synced_context(const std::string& commandname, const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool synced_context::run_and_store(const std::string& commandname, const config& data, bool use_undo, bool show, synced_command::error_handler_function error_handler)
|
||||
{
|
||||
assert(recorder.at_end());
|
||||
recorder.add_synced_command(commandname, data);
|
||||
bool success = run(commandname, data, use_undo, show, error_handler);
|
||||
if(!success)
|
||||
{
|
||||
recorder.undo();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool synced_context::run_and_throw(const std::string& commandname, const config& data, bool use_undo, bool show, synced_command::error_handler_function error_handler)
|
||||
{
|
||||
bool success = run_and_store(commandname, data, use_undo, show, error_handler);
|
||||
if(success)
|
||||
{
|
||||
resources::controller->maybe_throw_return_to_play_side();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool synced_context::run_in_synced_context_if_not_already(const std::string& commandname,const config& data, bool use_undo, bool show, synced_command::error_handler_function error_handler)
|
||||
{
|
||||
|
@ -112,7 +119,7 @@ bool synced_context::run_in_synced_context_if_not_already(const std::string& com
|
|||
ERR_REPLAY << "ignored attempt to invoke a synced command during replay\n";
|
||||
return false;
|
||||
}
|
||||
return run_in_synced_context(commandname, data, use_undo, show, true, error_handler);
|
||||
return run_and_throw(commandname, data, use_undo, show, error_handler);
|
||||
}
|
||||
case(synced_context::LOCAL_CHOICE):
|
||||
ERR_REPLAY << "trying to execute action while being in a local_choice" << std::endl;
|
||||
|
@ -125,7 +132,7 @@ bool synced_context::run_in_synced_context_if_not_already(const std::string& com
|
|||
synced_command::map::iterator it = synced_command::registry().find(commandname);
|
||||
if(it == synced_command::registry().end())
|
||||
{
|
||||
error_handler("commandname [" +commandname +"]not found", true);
|
||||
error_handler("commandname [" +commandname +"] not found", true);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -48,7 +48,6 @@ public:
|
|||
also there are no events of similar fired when redoing an action (in most cases).
|
||||
|
||||
@param use_undo this parameter is used to ignore undos during an ai move to optimize.
|
||||
@param store_in_replay only true if called by do_replay_handle
|
||||
@param error_handler an error handler for the case that data contains invalid data.
|
||||
|
||||
@return true if the action was successful.
|
||||
|
@ -56,7 +55,9 @@ public:
|
|||
|
||||
|
||||
*/
|
||||
static bool run_in_synced_context(const std::string& commandname,const config& data, bool use_undo = true, bool show = true , bool store_in_replay = true , synced_command::error_handler_function error_handler = default_error_function);
|
||||
static bool run(const std::string& commandname, const config& data, bool use_undo = true, bool show = true, synced_command::error_handler_function error_handler = default_error_function);
|
||||
static bool run_and_store(const std::string& commandname, const config& data, bool use_undo = true, bool show = true, synced_command::error_handler_function error_handler = default_error_function);
|
||||
static bool run_and_throw(const std::string& commandname, const config& data, bool use_undo = true, bool show = true, synced_command::error_handler_function error_handler = default_error_function);
|
||||
/**
|
||||
checks whether we are currently running in a synced context, and if not we enters it.
|
||||
this is never called from so_replay_handle.
|
||||
|
|
|
@ -985,8 +985,10 @@ int main(int argc, char** argv)
|
|||
return 1;
|
||||
} catch(CVideo::quit&) {
|
||||
//just means the game should quit
|
||||
} catch(end_level_exception&) {
|
||||
std::cerr << "caught end_level_exception (quitting)\n";
|
||||
} catch(return_to_play_side_exception&) {
|
||||
std::cerr << "caught return_to_play_side_exception, please report this bug (quitting)\n";
|
||||
} catch(quit_game_exception&) {
|
||||
std::cerr << "caught quit_game_exception (quitting)\n";
|
||||
} catch(twml_exception& e) {
|
||||
std::cerr << "WML exception:\nUser message: "
|
||||
<< e.user_message << "\nDev message: " << e.dev_message << '\n';
|
||||
|
|
|
@ -225,8 +225,7 @@ void move::execute(bool& success, bool& complete)
|
|||
try {
|
||||
events::mouse_handler& mouse_handler = resources::controller->get_mouse_handler_base();
|
||||
num_steps = mouse_handler.move_unit_along_route(steps, interrupted);
|
||||
} catch (restart_turn_exception&) {
|
||||
//This exception is thown by the ai code, i dont know whther the whiteboard can interact with the ai so i leave this catch here for now
|
||||
} catch (return_to_play_side_exception&) {
|
||||
set_arrow_brightness(ARROW_BRIGHTNESS_STANDARD);
|
||||
throw; // we rely on the caller to delete this action
|
||||
}
|
||||
|
|
|
@ -126,11 +126,10 @@ void recall::execute(bool& success, bool& complete)
|
|||
cost=temp_unit_->recall_cost();
|
||||
}
|
||||
current_team.get_side_actions()->change_gold_spent_by(-cost);
|
||||
bool const result = synced_context::run_in_synced_context("recall",
|
||||
bool const result = synced_context::run_and_throw("recall",
|
||||
replay_helper::get_recall(temp_unit_->id(), recall_hex_, map_location::null_location()),
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
synced_context::ignore_error_function);
|
||||
|
||||
if (!result) {
|
||||
|
|
|
@ -336,8 +336,7 @@ bool side_actions::execute(side_actions::iterator position)
|
|||
bool action_complete;
|
||||
try {
|
||||
action->execute(action_successful, action_complete);
|
||||
} catch (restart_turn_exception&) {
|
||||
//This exception is thown by the ai code, i dont know whther the whiteboard can interact with the ai so i leave this catch here for now
|
||||
} catch (return_to_play_side_exception&) {
|
||||
synced_erase(position);
|
||||
LOG_WB << "End turn exception caught during execution, deleting action. " << *this << "\n";
|
||||
//validate actions at next map rebuild
|
||||
|
|
Loading…
Add table
Reference in a new issue