move mp countdown code to new class
This commit is contained in:
parent
f16a0f6e61
commit
781df37ca4
6 changed files with 127 additions and 98 deletions
|
@ -773,6 +773,7 @@ set(wesnoth-main_SRC
|
|||
game_initialization/configure_engine.cpp
|
||||
game_initialization/connect_engine.cpp
|
||||
controller_base.cpp
|
||||
countdown_clock.cpp
|
||||
game_initialization/create_engine.cpp
|
||||
game_initialization/depcheck.cpp
|
||||
desktop/notifications.cpp
|
||||
|
|
|
@ -245,6 +245,7 @@ wesnoth_sources = Split("""
|
|||
game_initialization/configure_engine.cpp
|
||||
game_initialization/connect_engine.cpp
|
||||
controller_base.cpp
|
||||
countdown_clock.cpp
|
||||
game_initialization/create_engine.cpp
|
||||
desktop/notifications.cpp
|
||||
desktop/open.cpp
|
||||
|
|
73
src/countdown_clock.cpp
Normal file
73
src/countdown_clock.cpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
|
||||
#include "countdown_clock.hpp"
|
||||
|
||||
#include "team.hpp"
|
||||
#include "saved_game.hpp"
|
||||
#include "preferences.hpp"
|
||||
#include "sound.hpp"
|
||||
|
||||
namespace {
|
||||
const int WARNTIME = 20000; //start beeping when 20 seconds are left (20,000ms)
|
||||
unsigned timer_refresh = 0;
|
||||
const unsigned timer_refresh_rate = 50; // prevents calling SDL_GetTicks() too frequently
|
||||
}
|
||||
|
||||
|
||||
countdown_clock::countdown_clock(team& team, const mp_game_settings& settings)
|
||||
: team_(team)
|
||||
, settings_(settings)
|
||||
, last_timestamp_(SDL_GetTicks())
|
||||
, playing_sound_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
countdown_clock::~countdown_clock()
|
||||
{
|
||||
if(playing_sound_)
|
||||
{
|
||||
sound::stop_bell();
|
||||
}
|
||||
}
|
||||
|
||||
int countdown_clock::update_timestamp(int new_timestamp)
|
||||
{
|
||||
int res = std::max<int>(0, new_timestamp - last_timestamp_);
|
||||
last_timestamp_ = new_timestamp;
|
||||
return res;
|
||||
}
|
||||
|
||||
void countdown_clock::update_team(int new_timestamp)
|
||||
{
|
||||
int time_passed = update_timestamp(new_timestamp);
|
||||
team_.set_countdown_time(std::max<int>(0, team_.countdown_time() - time_passed));
|
||||
}
|
||||
|
||||
//make sure we think about countdown even while dialogs are open
|
||||
void countdown_clock::process(events::pump_info &info)
|
||||
{
|
||||
if(info.ticks(&timer_refresh, timer_refresh_rate)) {
|
||||
update(info.ticks());
|
||||
}
|
||||
}
|
||||
|
||||
bool countdown_clock::update(int new_timestamp)
|
||||
{
|
||||
update_team(new_timestamp);
|
||||
maybe_play_sound();
|
||||
return team_.countdown_time() > 0;
|
||||
}
|
||||
|
||||
void countdown_clock::maybe_play_sound()
|
||||
{
|
||||
if(!playing_sound_ && team_.countdown_time() < WARNTIME )
|
||||
{
|
||||
if(preferences::turn_bell() || preferences::sound_on() || preferences::UI_sound_on())
|
||||
{
|
||||
const int loop_ticks = team_.countdown_time();
|
||||
const int fadein_ticks = (loop_ticks > WARNTIME / 2) ? loop_ticks - WARNTIME / 2 : 0;
|
||||
sound::play_timer(game_config::sounds::timer_bell, loop_ticks, fadein_ticks);
|
||||
playing_sound_ = true;
|
||||
}
|
||||
}
|
||||
}
|
28
src/countdown_clock.hpp
Normal file
28
src/countdown_clock.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
#include "events.hpp"
|
||||
#include <SDL_timer.h>
|
||||
|
||||
class team;
|
||||
struct mp_game_settings;
|
||||
class countdown_clock : public events::pump_monitor
|
||||
{
|
||||
public:
|
||||
countdown_clock(team& team, const mp_game_settings& settings);
|
||||
~countdown_clock();
|
||||
/// @returns ticks passed since last update
|
||||
/// @param new_timestamp latest result of SDL_GetTicks()
|
||||
int update_timestamp(int new_timestamp);
|
||||
/// @param new_timestamp latest result of SDL_GetTicks()
|
||||
void update_team(int new_timestamp);
|
||||
void process(events::pump_info &info);
|
||||
/// @return whether there is time left
|
||||
/// @param new_timestamp latest result of SDL_GetTicks()
|
||||
bool update(int new_timestamp = SDL_GetTicks());
|
||||
void maybe_play_sound();
|
||||
private:
|
||||
team& team_;
|
||||
const mp_game_settings& settings_;
|
||||
int last_timestamp_;
|
||||
bool playing_sound_;
|
||||
};
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
#include "formula_string_utils.hpp"
|
||||
#include "unit_animation.hpp"
|
||||
#include "whiteboard/manager.hpp"
|
||||
|
||||
#include "countdown_clock.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
static lg::log_domain log_engine("engine");
|
||||
|
@ -45,7 +45,6 @@ playmp_controller::playmp_controller(const config& level,
|
|||
bool skip_replay, bool blindfold_replay_, bool is_host)
|
||||
: playsingle_controller(level, state_of_game, ticks,
|
||||
game_config, tdata, video, skip_replay || blindfold_replay_) //this || means that if blindfold is enabled, quick replays will be on.
|
||||
, beep_warning_time_(0)
|
||||
, network_processing_stopped_(false)
|
||||
, blindfold_(*gui_,blindfold_replay_)
|
||||
{
|
||||
|
@ -66,11 +65,6 @@ playmp_controller::playmp_controller(const config& level,
|
|||
playmp_controller::~playmp_controller() {
|
||||
//halt and cancel the countdown timer
|
||||
try {
|
||||
|
||||
if(beep_warning_time_ < 0) {
|
||||
sound::stop_bell();
|
||||
}
|
||||
|
||||
turn_data_.host_transfer().detach_handler(this);
|
||||
} catch (...) {}
|
||||
}
|
||||
|
@ -114,51 +108,15 @@ void playmp_controller::remove_blindfold() {
|
|||
}
|
||||
}
|
||||
|
||||
bool playmp_controller::counting_down() {
|
||||
return beep_warning_time_ > 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
const int WARNTIME = 20000; //start beeping when 20 seconds are left (20,000ms)
|
||||
unsigned timer_refresh = 0;
|
||||
const unsigned timer_refresh_rate = 50; // prevents calling SDL_GetTicks() too frequently
|
||||
}
|
||||
|
||||
//make sure we think about countdown even while dialogs are open
|
||||
void playmp_controller::process(events::pump_info &info) {
|
||||
if(playmp_controller::counting_down()) {
|
||||
if(info.ticks(&timer_refresh, timer_refresh_rate)) {
|
||||
playmp_controller::think_about_countdown(info.ticks());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void playmp_controller::reset_countdown()
|
||||
{
|
||||
if (beep_warning_time_ < 0)
|
||||
sound::stop_bell();
|
||||
beep_warning_time_ = 0;
|
||||
}
|
||||
|
||||
//check if it is time to start playing the timer warning
|
||||
void playmp_controller::think_about_countdown(int ticks) {
|
||||
if(ticks >= beep_warning_time_) {
|
||||
const bool bell_on = preferences::turn_bell();
|
||||
if(bell_on || preferences::sound_on() || preferences::UI_sound_on()) {
|
||||
const int loop_ticks = WARNTIME - (ticks - beep_warning_time_);
|
||||
const int fadein_ticks = (loop_ticks > WARNTIME / 2) ? loop_ticks - WARNTIME / 2 : 0;
|
||||
sound::play_timer(game_config::sounds::timer_bell, loop_ticks, fadein_ticks);
|
||||
beep_warning_time_ = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
possible_end_play_signal playmp_controller::play_human_turn()
|
||||
{
|
||||
LOG_NG << "playmp::play_human_turn...\n";
|
||||
|
||||
remove_blindfold();
|
||||
int cur_ticks = SDL_GetTicks();
|
||||
boost::scoped_ptr<countdown_clock> timer;
|
||||
if(!linger_ && saved_game_.mp_settings().mp_countdown) {
|
||||
timer.reset(new countdown_clock(current_team(), saved_game_.mp_settings()));
|
||||
}
|
||||
show_turn_dialog();
|
||||
|
||||
if (!preferences::disable_auto_moves()) {
|
||||
|
@ -210,36 +168,17 @@ possible_end_play_signal playmp_controller::play_human_turn()
|
|||
}
|
||||
|
||||
HANDLE_END_PLAY_SIGNAL( play_slice() );
|
||||
|
||||
if (!linger_ && (current_team().countdown_time() > 0) && saved_game_.mp_settings().mp_countdown) {
|
||||
SDL_Delay(1);
|
||||
const int ticks = SDL_GetTicks();
|
||||
int new_time = current_team().countdown_time()-std::max<int>(1,(ticks - cur_ticks));
|
||||
if (new_time > 0 ){
|
||||
current_team().set_countdown_time(new_time);
|
||||
cur_ticks = ticks;
|
||||
if(current_team().is_local_human() && !beep_warning_time_) {
|
||||
beep_warning_time_ = new_time - WARNTIME + ticks;
|
||||
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;
|
||||
}
|
||||
if(counting_down()) {
|
||||
think_about_countdown(ticks);
|
||||
}
|
||||
} else {
|
||||
// Clock time ended
|
||||
// If no turn bonus or action bonus -> defeat
|
||||
const int action_increment = saved_game_.mp_settings().mp_countdown_action_bonus;
|
||||
if ( (saved_game_.mp_settings().mp_countdown_turn_bonus == 0 )
|
||||
&& (action_increment == 0 || current_team().action_bonus_count() == 0)) {
|
||||
// Not possible to end level in MP with throw end_level_exception(DEFEAT);
|
||||
// because remote players only notice network disconnection
|
||||
// Current solution end remaining turns automatically
|
||||
current_team().set_countdown_time(10);
|
||||
}
|
||||
|
||||
return boost::none;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
turn_data_.send_data();
|
||||
|
@ -325,9 +264,6 @@ void playmp_controller::linger()
|
|||
set_completion setter(saved_game_,"running");
|
||||
// End all unit moves
|
||||
gamestate_.board_.set_all_units_user_end_turn();
|
||||
//current_team().set_countdown_time(0);
|
||||
//halt and cancel the countdown timer
|
||||
reset_countdown();
|
||||
|
||||
set_end_scenario_button();
|
||||
|
||||
|
@ -407,20 +343,20 @@ void playmp_controller::wait_for_upload()
|
|||
}
|
||||
|
||||
void playmp_controller::after_human_turn(){
|
||||
if ( saved_game_.mp_settings().mp_countdown ){
|
||||
const int action_increment = saved_game_.mp_settings().mp_countdown_action_bonus;
|
||||
const int maxtime = saved_game_.mp_settings().mp_countdown_reservoir_time;
|
||||
int secs = (current_team().countdown_time() / 1000) + saved_game_.mp_settings().mp_countdown_turn_bonus;
|
||||
secs += action_increment * current_team().action_bonus_count();
|
||||
if(saved_game_.mp_settings().mp_countdown)
|
||||
{
|
||||
//time_left + turn_bonus + (action_bouns * number of actions done)
|
||||
const int new_time_in_secs = (current_team().countdown_time() / 1000)
|
||||
+ saved_game_.mp_settings().mp_countdown_turn_bonus
|
||||
+ saved_game_.mp_settings().mp_countdown_action_bonus * current_team().action_bonus_count();
|
||||
const int new_time = 1000 * std::min<int>(new_time_in_secs, saved_game_.mp_settings().mp_countdown_reservoir_time);
|
||||
|
||||
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_);
|
||||
current_team().set_countdown_time(new_time);
|
||||
recorder.add_countdown_update(new_time, player_number_);
|
||||
}
|
||||
LOG_NG << "playmp::after_human_turn...\n";
|
||||
|
||||
|
||||
|
||||
// Normal post-processing for human turns (clear undos, end the turn, etc.)
|
||||
playsingle_controller::after_human_turn();
|
||||
//send one more time to make sure network is up-to-date.
|
||||
|
@ -430,11 +366,6 @@ void playmp_controller::after_human_turn(){
|
|||
|
||||
void playmp_controller::finish_side_turn(){
|
||||
play_controller::finish_side_turn();
|
||||
|
||||
|
||||
//halt and cancel the countdown timer
|
||||
reset_countdown();
|
||||
|
||||
}
|
||||
|
||||
possible_end_play_signal playmp_controller::play_network_turn(){
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
class turn_info;
|
||||
|
||||
class playmp_controller : public playsingle_controller, public events::pump_monitor, public syncmp_handler
|
||||
class playmp_controller : public playsingle_controller, public syncmp_handler
|
||||
{
|
||||
public:
|
||||
playmp_controller(const config& level, saved_game& state_of_game,
|
||||
|
@ -33,10 +33,6 @@ public:
|
|||
static unsigned int replay_last_turn() { return replay_last_turn_; }
|
||||
static void set_replay_last_turn(unsigned int turn);
|
||||
|
||||
bool counting_down();
|
||||
void reset_countdown();
|
||||
void think_about_countdown(int ticks);
|
||||
void process(events::pump_info &info);
|
||||
void maybe_linger();
|
||||
void process_oos(const std::string& err_msg) const;
|
||||
|
||||
|
@ -63,7 +59,6 @@ protected:
|
|||
/** Wait for the host to upload the next scenario. */
|
||||
void wait_for_upload();
|
||||
|
||||
int beep_warning_time_;
|
||||
mutable bool network_processing_stopped_;
|
||||
|
||||
virtual void on_not_observer();
|
||||
|
|
Loading…
Add table
Reference in a new issue