void playmp_controller::after_human_turn(){ if ( gamestate_.mp_settings().mp_countdown ){ const int action_increment = gamestate_.mp_settings().mp_countdown_action_bonus; const int maxtime = gamestate_.mp_settings().mp_countdown_reservoir_time; int secs = (current_team().countdown_time() / 1000) + gamestate_.mp_settings().mp_countdown_turn_bonus; secs += action_increment * current_team().action_bonus_count(); current_team().set_action_bonus_count(0); secs = (secs > maxtime) ? maxtime : secs; current_team().set_countdown_time(1000 * secs); recorder.add_countdown_update(current_team().countdown_time(),player_number_); } LOG_NG << "playmp::after_human_turn...\n"; end_turn_record(); //ensure that turn_data_ is constructed before it is used. if (turn_data_ == NULL) init_turn_data(); //send one more time to make sure network is up-to-date. playsingle_controller::after_human_turn(); turn_data_->send_data(); if (turn_data_ != NULL){ turn_data_->host_transfer().detach_handler(this); delete turn_data_; turn_data_ = NULL; } }
void playmp_controller::wait_for_upload() { // If the host is here we'll never leave since we wait for the host to // upload the next scenario. assert(!is_host_); const bool set_turn_data = (turn_data_ == 0); if(set_turn_data) { init_turn_data(); } while(true) { try { config cfg; const network::connection res = dialogs::network_receive_dialog(*gui_, _("Waiting for next scenario..."), cfg); std::deque<config> backlog; if(res != network::null_connection) { if (turn_data_->process_network_data(cfg, res, backlog, skip_replay_) == turn_info::PROCESS_END_LINGER) { break; } } } catch(end_level_exception& e) { turn_data_->send_data(); throw e; } } if(set_turn_data) { release_turn_data(); } }
void playmp_controller::before_human_turn(bool save){ LOG_NG << "playmp::before_human_turn...\n"; playsingle_controller::before_human_turn(save); init_turn_data(); }
void playmp_controller::linger() { LOG_NG << "beginning end-of-scenario linger\n"; browse_ = true; linger_ = true; // If we need to set the status depending on the completion state // we're needed here. gui_->set_game_mode(game_display::LINGER_MP); // this is actually for after linger mode is over -- we don't want to // stay stuck in linger state when the *next* scenario is over. gamestate_.classification().completion = "running"; // End all unit moves for (unit_map::iterator u = units_.begin(); u != units_.end(); ++ u) { u->set_user_end_turn(true); } //current_team().set_countdown_time(0); //halt and cancel the countdown timer reset_countdown(); set_end_scenario_button(); if ( get_end_level_data().reveal_map ) { // switch to observer viewpoint gui_->set_team(0,true); gui_->recalculate_minimap(); gui_->invalidate_all(); gui_->draw(true,true); } bool quit; do { quit = true; try { // reimplement parts of play_side() player_number_ = first_player_; init_turn_data(); play_human_turn(); turn_over_ = true; // We don't want to linger mode to add end_turn to replay 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 (end_turn_exception&) { // thrown if the host leaves the game (sends [leave_game]), we need // to stay in this loop to stay in linger mode, otherwise the game // gets aborted LOG_NG << "caught end-turn-exception" << std::endl; quit = false; } catch (network::error&) { LOG_NG << "caught network-error-exception" << std::endl; quit = false; } } while (!quit); reset_end_scenario_button(); LOG_NG << "ending end-of-scenario linger\n"; }
void playmp_controller::before_human_turn(bool save) { playsingle_controller::before_human_turn(save); init_turn_data(); }
void playmp_controller::play_side() { utils::string_map player; player["name"] = current_team().current_player(); std::string turn_notification_msg = _("$name has taken control"); turn_notification_msg = utils::interpolate_variables_into_string(turn_notification_msg, &player); gui_->send_notification(_("Turn changed"), turn_notification_msg); int end_ticks = calculate_end_ticks(); player_type_changed_ = false; while (unit_map::main_ticks < end_ticks && !player_type_changed_) { VALIDATE(!unit::actor, "playmp_controller::play_side, unit::actor isn't NULL!"); if (!skip_next_turn_) { end_turn_ = false; } unit* u = &units_.current_unit(); if (!tent::turn_based) { int past_ticks = u->backward_ticks(u->ticks()); if (unit_map::main_ticks + past_ticks >= end_ticks) { units_.do_escape_ticks_uh(teams_, *gui_, end_ticks - unit_map::main_ticks, false); autosave_ticks_ = -1; continue; } units_.do_escape_ticks_uh(teams_, *gui_, past_ticks, true); } else { if (u->side() < player_number_) { unit_map::main_ticks = end_ticks; player_number_ = 1; continue; } } // if exist spirit feature/technology, second maybe goto first. need reget u = &units_.current_unit(); player_number_ = u->side(); // init_turn_data need player_number_ be valid. team& t = teams_[player_number_ - 1]; bool local = t.is_local(); bool new_side = false; if (local || loading_game_) { if (local) { init_turn_data(); } new_side = do_prefix_unit(end_ticks, loading_game_, false); } if (t.is_network()) { play_network_turn(); } else if (actor_can_continue_action(units_, player_number_)) { // we can't call playsingle_controller::play_side because // we need to catch exception here if (t.is_human()) { try { if (!loading_game_ && unit::actor->human_team_can_ai()) { play_ai_turn(turn_data_); } before_human_turn(new_side); play_human_turn(); after_human_turn(); } catch (end_turn_exception& end_turn) { if (end_turn.redo == player_number_ - 1) { player_type_changed_ = true; // if new controller is not human, // reset gui to prev human one if (!teams_[player_number_ - 2].is_human()) { browse_ = true; int t = find_human_team_before(player_number_ - 1); if (t <= 0) t = gui_->get_playing_team() + 1; gui_->set_team(t-1); gui_->recalculate_minimap(); gui_->invalidate_all(); gui_->draw(true,true); } } else { after_human_turn(); } } } else if (t.is_ai()) { play_ai_turn(turn_data_); } } if (local) { do_post_unit(false); release_turn_data(); } loading_game_ = false; } //keep looping if the type of a team (human/ai/networked) has changed mid-turn skip_next_turn_ = false; }