Adding support for observers in multiplayer to pause...

...and continue the game at any time (special greetings to boucman ;-).
This commit is contained in:
Jörg Hinrichs 2009-02-08 22:15:06 +00:00
parent 9c55b5b6ab
commit 9c7884f6fb
6 changed files with 72 additions and 31 deletions

View file

@ -11,6 +11,8 @@ Version 1.5.9+svn:
* Updated maps: 4p Clash.
* User interface:
* Fixed an exception when a certain characters weren't escaped
* Multiplayer
* Added support for observers to pause and continue the game at any time
* Miscellaneous and bug fixes:
* Fix bug #12946: [menu_item]/[command] losing function when called again
* Fix flickering of units in the second part of the tutorial (bug #12923)

View file

@ -119,7 +119,7 @@
id=menu-main
title= _ "Menu"
image=lite
items=objectives,statistics,unitlist,statustable,save,savereplay,savemap,load,preferences,chatlog,AUTOSAVES,help,quit
items=objectives,statistics,unitlist,statustable,save,savereplay,savemap,load,preferences,chatlog,AUTOSAVES,help,stopnetwork,startnetwork,quit
ref=top-panel
rect="=+3,=+1,+100,=-4"
xanchor=fixed

View file

@ -77,6 +77,8 @@ const struct {
{ hotkey::HOTKEY_OBJECTIVES, "objectives", N_("Scenario Objectives"), false, hotkey::SCOPE_GAME },
{ hotkey::HOTKEY_UNIT_LIST, "unitlist", N_("Unit List"), false, hotkey::SCOPE_GAME },
{ hotkey::HOTKEY_STATISTICS, "statistics", N_("Statistics"), false, hotkey::SCOPE_GAME },
{ hotkey::HOTKEY_STOP_NETWORK, "stopnetwork", N_("Stop"), false, hotkey::SCOPE_GAME },
{ hotkey::HOTKEY_START_NETWORK, "startnetwork", N_("Play"), false, hotkey::SCOPE_GAME },
{ hotkey::HOTKEY_QUIT_GAME, "quit", N_("Quit Game"), false, hotkey::SCOPE_GENERAL },
{ hotkey::HOTKEY_LABEL_TEAM_TERRAIN, "labelteamterrain", N_("Set Team Label"), false, hotkey::SCOPE_GAME },
{ hotkey::HOTKEY_LABEL_TERRAIN, "labelterrain", N_("Set Label"), false, hotkey::SCOPE_GAME },
@ -762,6 +764,12 @@ bool command_executor::execute_command(HOTKEY_COMMAND command, int /*index*/)
case HOTKEY_STATISTICS:
show_statistics();
break;
case HOTKEY_STOP_NETWORK:
stop_network();
break;
case HOTKEY_START_NETWORK:
start_network();
break;
case HOTKEY_LABEL_TEAM_TERRAIN:
label_terrain(true);
break;

View file

@ -50,7 +50,7 @@ enum HOTKEY_COMMAND {
HOTKEY_RECRUIT, HOTKEY_REPEAT_RECRUIT, HOTKEY_RECALL, HOTKEY_ENDTURN,
HOTKEY_TOGGLE_GRID, HOTKEY_STATUS_TABLE, HOTKEY_MUTE, HOTKEY_MOUSE_SCROLL,
HOTKEY_SPEAK, HOTKEY_CREATE_UNIT, HOTKEY_CHANGE_UNIT_SIDE, HOTKEY_PREFERENCES,
HOTKEY_OBJECTIVES, HOTKEY_UNIT_LIST, HOTKEY_STATISTICS, HOTKEY_QUIT_GAME,
HOTKEY_OBJECTIVES, HOTKEY_UNIT_LIST, HOTKEY_STATISTICS, HOTKEY_STOP_NETWORK, HOTKEY_START_NETWORK, HOTKEY_QUIT_GAME,
HOTKEY_LABEL_TEAM_TERRAIN, HOTKEY_LABEL_TERRAIN, HOTKEY_CLEAR_LABELS,HOTKEY_SHOW_ENEMY_MOVES, HOTKEY_BEST_ENEMY_MOVES,
HOTKEY_DELAY_SHROUD, HOTKEY_UPDATE_SHROUD, HOTKEY_CONTINUE_MOVE,
HOTKEY_SEARCH, HOTKEY_SPEAK_ALLY, HOTKEY_SPEAK_ALL, HOTKEY_HELP,
@ -265,6 +265,8 @@ public:
virtual void objectives() {}
virtual void unit_list() {}
virtual void show_statistics() {}
virtual void stop_network() {}
virtual void start_network() {}
virtual void label_terrain(bool /*team_only*/) {}
virtual void clear_labels() {}
virtual void show_enemy_moves(bool /*ignore_units*/) {}

View file

@ -45,7 +45,7 @@ playmp_controller::playmp_controller(const config& level,
skip_replay_ = false;
}
network_processing_stopped_ = false;
}
@ -76,6 +76,16 @@ void playmp_controller::shout(){
menu_handler_.shout();
}
void playmp_controller::start_network(){
network_processing_stopped_ = false;
LOG_NG << "network processing activated again";
}
void playmp_controller::stop_network(){
network_processing_stopped_ = true;
LOG_NG << "network processing stopped";
}
void playmp_controller::play_side(const unsigned int team_index, bool save){
do {
player_type_changed_ = false;
@ -468,42 +478,48 @@ void playmp_controller::play_network_turn(){
for(;;) {
bool have_data = false;
config cfg;
if (!network_processing_stopped_){
bool have_data = false;
config cfg;
network::connection from = network::null_connection;
network::connection from = network::null_connection;
if(data_backlog_.empty() == false) {
have_data = true;
cfg = data_backlog_.front();
data_backlog_.pop_front();
} else {
from = network::receive_data(cfg);
have_data = from != network::null_connection;
}
if(have_data) {
if (skip_replay_ && replay_last_turn_ <= status_.turn()){
skip_replay_ = false;
if(data_backlog_.empty() == false) {
have_data = true;
cfg = data_backlog_.front();
data_backlog_.pop_front();
} else {
from = network::receive_data(cfg);
have_data = from != network::null_connection;
}
try{
const turn_info::PROCESS_DATA_RESULT result = turn_data.process_network_data(cfg,from,data_backlog_,skip_replay_);
if(result == turn_info::PROCESS_RESTART_TURN) {
player_type_changed_ = true;
return;
} else if(result == turn_info::PROCESS_END_TURN) {
break;
if(have_data) {
if (skip_replay_ && replay_last_turn_ <= status_.turn()){
skip_replay_ = false;
}
try{
const turn_info::PROCESS_DATA_RESULT result = turn_data.process_network_data(cfg,from,data_backlog_,skip_replay_);
if(result == turn_info::PROCESS_RESTART_TURN) {
player_type_changed_ = true;
return;
} else if(result == turn_info::PROCESS_END_TURN) {
break;
}
}
catch (replay::error e){
process_oos(e.message);
throw e;
}
}
catch (replay::error e){
process_oos(e.message);
throw e;
}
}
}
play_slice();
turn_data.send_data();
if (!network_processing_stopped_){
turn_data.send_data();
}
gui_->draw();
}
@ -564,6 +580,16 @@ bool playmp_controller::can_execute_command(hotkey::HOTKEY_COMMAND command, int
case hotkey::HOTKEY_SPEAK_ALL:
res = res && network::nconnections() > 0;
break;
case hotkey::HOTKEY_START_NETWORK:
case hotkey::HOTKEY_STOP_NETWORK:
res = is_observer();
break;
case hotkey::HOTKEY_STOP_REPLAY:
if (is_observer()){
network_processing_stopped_ = true;
LOG_NG << "network processing stopped";
}
break;
default:
return playsingle_controller::can_execute_command(command, index);
}

View file

@ -53,6 +53,8 @@ protected:
virtual void whisper();
virtual void shout();
virtual void clear_labels();
virtual void start_network();
virtual void stop_network();
virtual bool can_execute_command(hotkey::HOTKEY_COMMAND command, int index=-1) const;
virtual void play_side(const unsigned int team_index, bool save);
@ -65,6 +67,7 @@ protected:
turn_info* turn_data_;
int beep_warning_time_;
mutable bool network_processing_stopped_;
private:
void process_oos(const std::string& err_msg);
void set_end_scenario_button();