improvements to the way network games are set up
This commit is contained in:
parent
540c2e8345
commit
0946c4b945
9 changed files with 207 additions and 148 deletions
|
@ -341,6 +341,7 @@ vacant_slots="Vacant Slots"
|
|||
|
||||
host_game="Host Multiplayer Game"
|
||||
join_game="Join Game"
|
||||
observe_game="Observe Game"
|
||||
load_game="Load Game"
|
||||
create_new_game="Create Game"
|
||||
name_of_game="Name of game"
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 755 B After Width: | Height: | Size: 875 B |
|
@ -8,6 +8,7 @@
|
|||
#include "replay.hpp"
|
||||
#include "scoped_resource.hpp"
|
||||
#include "show_dialog.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
@ -35,59 +36,6 @@ private:
|
|||
config cfg;
|
||||
};
|
||||
|
||||
enum GAME_LIST_RESULT { QUIT_GAME, CREATE_GAME, JOIN_GAME };
|
||||
|
||||
GAME_LIST_RESULT manage_game_list(display& disp, const config* gamelist)
|
||||
{
|
||||
gamelist_manager manager;
|
||||
for(;;) {
|
||||
std::vector<std::string> options;
|
||||
options.push_back(string_table["create_new_game"]);
|
||||
for(config::const_child_itors i = gamelist->child_range("game");
|
||||
i.first != i.second; ++i.first) {
|
||||
options.push_back((**i.first)["name"]);
|
||||
}
|
||||
|
||||
options.push_back(string_table["quit_button"]);
|
||||
|
||||
const int res = gui::show_dialog(disp,NULL,"","Choose game to join",
|
||||
gui::MESSAGE,&options,NULL,"",NULL,&manager);
|
||||
if(res == gamelist_manager::UPDATED_GAMELIST) {
|
||||
gamelist = manager.get_gamelist();
|
||||
} else if(res == 0) {
|
||||
std::string name;
|
||||
const int res = gui::show_dialog(disp,NULL,"","Name your game:",
|
||||
gui::OK_CANCEL,NULL,NULL,"Name:",&name);
|
||||
if(res == 0) {
|
||||
config response;
|
||||
config& create_game = response.add_child("create_game");;
|
||||
create_game["name"] = name;
|
||||
|
||||
network::send_data(response);
|
||||
|
||||
return CREATE_GAME;
|
||||
}
|
||||
} else if(size_t(res) == options.size()-1) {
|
||||
return QUIT_GAME;
|
||||
} else if(res > 0 && size_t(res) < options.size()) {
|
||||
const config::const_child_itors i = gamelist->child_range("game");
|
||||
const size_t index = size_t(res)-1;
|
||||
assert(i.second - i.first > int(index));
|
||||
const std::string& id = (**(i.first+index))["id"];
|
||||
|
||||
config response;
|
||||
config& join = response.add_child("join");
|
||||
join["id"] = id;
|
||||
|
||||
network::send_data(response);
|
||||
|
||||
return JOIN_GAME;
|
||||
}
|
||||
}
|
||||
|
||||
return QUIT_GAME;
|
||||
}
|
||||
|
||||
void check_response(network::connection res, const config& data)
|
||||
{
|
||||
if(!res) {
|
||||
|
@ -116,7 +64,7 @@ void receive_gamelist(display& disp, config& data)
|
|||
class wait_for_start : public lobby::dialog
|
||||
{
|
||||
public:
|
||||
wait_for_start(display& disp, config& cfg) : got_side(false), status(START_GAME), disp_(disp), cancel_button_(NULL), sides_(cfg) {}
|
||||
wait_for_start(display& disp, config& cfg, int team_num) : got_side(false), team(team_num), status(START_GAME), disp_(disp), cancel_button_(NULL), sides_(cfg) {}
|
||||
|
||||
void set_area(const SDL_Rect& area) {
|
||||
const std::string text = string_table["waiting_start"];
|
||||
|
@ -146,6 +94,13 @@ public:
|
|||
const network::connection res = network::receive_data(reply);
|
||||
if(res) {
|
||||
std::cerr << "received data while waiting: " << reply.write() << "\n";
|
||||
const config::child_list& assigns = reply.get_children("reassign_side");
|
||||
for(config::child_list::const_iterator a = assigns.begin(); a != assigns.end(); ++a) {
|
||||
if(lexical_cast_default<int>((**a)["from"]) == team) {
|
||||
team = lexical_cast_default<int>((**a)["to"]);
|
||||
}
|
||||
}
|
||||
|
||||
if(reply.values["failed"] == "yes") {
|
||||
status = SIDE_UNAVAILABLE;
|
||||
return lobby::QUIT;
|
||||
|
@ -175,6 +130,7 @@ public:
|
|||
}
|
||||
|
||||
bool got_side;
|
||||
int team;
|
||||
enum { START_GAME, GAME_CANCELLED, SIDE_UNAVAILABLE } status;
|
||||
|
||||
private:
|
||||
|
@ -275,8 +231,7 @@ void play_multiplayer_client(display& disp, game_data& units_data, config& cfg,
|
|||
logged_in = true;
|
||||
}
|
||||
|
||||
for(bool first_time = true;
|
||||
(first_time || logged_in) && network::nconnections() > 0;
|
||||
for(bool first_time = true; (first_time || logged_in) && network::nconnections() > 0;
|
||||
first_time = false) {
|
||||
|
||||
if(!first_time) {
|
||||
|
@ -285,6 +240,8 @@ void play_multiplayer_client(display& disp, game_data& units_data, config& cfg,
|
|||
|
||||
std::cerr << "when receiving gamelist got '" << data.write() << "'\n";
|
||||
|
||||
bool observer = false;
|
||||
|
||||
//if we got a gamelist back - otherwise we have
|
||||
//got a description of the game back
|
||||
const config* const gamelist = data.child("gamelist");
|
||||
|
@ -310,6 +267,9 @@ void play_multiplayer_client(display& disp, game_data& units_data, config& cfg,
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
case lobby::OBSERVE:
|
||||
observer = true;
|
||||
case lobby::JOIN: {
|
||||
status = 1;
|
||||
break;
|
||||
|
@ -332,56 +292,41 @@ void play_multiplayer_client(display& disp, game_data& units_data, config& cfg,
|
|||
|
||||
//ensure we send a close game message to the server when we are done
|
||||
network_game_manager game_manager;
|
||||
|
||||
std::map<int,int> choice_map;
|
||||
std::vector<std::string> choices, race_names;
|
||||
std::vector<bool> changes_allowed;
|
||||
|
||||
const bool allow_observer = sides["observer"] != "no";
|
||||
|
||||
if(allow_observer) {
|
||||
choices.push_back(string_table["observer"]);
|
||||
}
|
||||
|
||||
const config::child_list& sides_list = sides.get_children("side");
|
||||
for(config::child_list::const_iterator s = sides_list.begin(); s != sides_list.end(); ++s) {
|
||||
if((**s)["controller"] == "network" &&
|
||||
(**s)["taken"] != "yes") {
|
||||
choice_map[choices.size()] = 1 + s - sides_list.begin();
|
||||
choices.push_back((**s)["name"] + "," + (**s)["type"] + "," + (**s)["description"]);
|
||||
|
||||
int team_num = 0;
|
||||
|
||||
if(!observer) {
|
||||
//search for an appropriate vacant slot. If a description is set
|
||||
//(i.e. we're loading from a saved game), then prefer to get the side
|
||||
//with the same description as our login. Otherwise just choose the first
|
||||
//available side.
|
||||
config::child_list::const_iterator side_choice = sides_list.end();
|
||||
int nchoice = -1, n = 1;
|
||||
bool allow_changes = false;
|
||||
std::string default_race;
|
||||
for(config::child_list::const_iterator s = sides_list.begin(); s != sides_list.end(); ++s, ++n) {
|
||||
if((**s)["controller"] == "network" &&
|
||||
(**s)["taken"] != "yes") {
|
||||
if(side_choice == sides_list.end() || (**s)["description"] == preferences::login()) {
|
||||
side_choice = s;
|
||||
nchoice = n;
|
||||
allow_changes = (**s)["changes_allowed"] != "no";
|
||||
default_race = (**s)["name"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
race_names.push_back((**s)["name"]);
|
||||
changes_allowed.push_back((**s)["allow_changes"] != "no");
|
||||
}
|
||||
if(side_choice == sides_list.end()) {
|
||||
gui::show_dialog(disp,NULL,"",string_table["no_sides_available"],gui::OK_ONLY);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(choices.empty()) {
|
||||
gui::show_dialog(disp,NULL,"",string_table["no_sides_available"],gui::OK_ONLY);
|
||||
continue;
|
||||
}
|
||||
|
||||
int choice = gui::show_dialog(disp,NULL,"",string_table["client_choose_side"],
|
||||
gui::OK_CANCEL,&choices);
|
||||
|
||||
if((choice != 0 || allow_observer == false) && choice_map.count(choice) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool observer = allow_observer && choice == 0;
|
||||
|
||||
const int team_num = observer ? -1 : choice_map[choice];
|
||||
|
||||
//send our choice of team to the server
|
||||
if(!observer) {
|
||||
|
||||
assert(team_num >= 1 && team_num <= race_names.size());
|
||||
const std::string& default_race = race_names[team_num-1];
|
||||
const bool allow_changes = changes_allowed[team_num-1];
|
||||
team_num = nchoice;
|
||||
|
||||
config response;
|
||||
std::stringstream stream;
|
||||
stream << team_num;
|
||||
response["side"] = stream.str();
|
||||
response["side"] = lexical_cast<std::string>(nchoice);
|
||||
response["description"] = preferences::login();
|
||||
|
||||
const std::string& era = sides["era"];
|
||||
|
@ -407,8 +352,9 @@ void play_multiplayer_client(display& disp, game_data& units_data, config& cfg,
|
|||
possible_sides.begin(); side != possible_sides.end(); ++side) {
|
||||
choices.push_back(translate_string_default((**side)["id"],(**side)["name"]));
|
||||
|
||||
if(choices.back() == default_race)
|
||||
if(choices.back() == default_race) {
|
||||
choice = side - possible_sides.begin();
|
||||
}
|
||||
}
|
||||
|
||||
//if the client is allowed to choose their team, instead of having
|
||||
|
@ -429,7 +375,7 @@ void play_multiplayer_client(display& disp, game_data& units_data, config& cfg,
|
|||
network::send_data(response);
|
||||
}
|
||||
|
||||
wait_for_start waiter(disp,sides);
|
||||
wait_for_start waiter(disp,sides,team_num);
|
||||
std::vector<std::string> messages;
|
||||
config game_data;
|
||||
const lobby::RESULT dialog_res = lobby::enter(disp,game_data,cfg,&waiter,messages);
|
||||
|
@ -450,6 +396,8 @@ void play_multiplayer_client(display& disp, game_data& units_data, config& cfg,
|
|||
if(!observer && !waiter.got_side) {
|
||||
throw network::error("Choice of team unavailable.");
|
||||
}
|
||||
|
||||
team_num = waiter.team;
|
||||
|
||||
//we want to make the network/human players look right from our
|
||||
//perspective
|
||||
|
|
|
@ -451,7 +451,7 @@ void mp_connect::gui_update()
|
|||
if (side["controller"] == "network") {
|
||||
if (side["description"] == "") {
|
||||
combos_type_[n].set_selected(0);
|
||||
} else if (side["description"] == "Computer Player") {
|
||||
} else if (side["description"] == string_table["ai_controlled"]) {
|
||||
//When loading a game you did not create AI players are marked
|
||||
//as network players, set back to AI
|
||||
combos_type_[n].set_selected(2);
|
||||
|
@ -855,47 +855,84 @@ void mp_connect::update_network()
|
|||
}
|
||||
}
|
||||
|
||||
const int side_taken = atoi(cfg["side"].c_str())-1;
|
||||
int side_taken = atoi(cfg["side"].c_str())-1;
|
||||
if(side_taken >= 0 && side_taken < int(sides.size())) {
|
||||
std::map<config*,network::connection>::iterator pos = positions_.find(sides[side_taken]);
|
||||
if(pos != positions_.end()) {
|
||||
if(!pos->second || pos->second == sock) {
|
||||
std::cerr << "client has taken a valid position\n";
|
||||
//see if we can reassign the player to a different position
|
||||
if(pos->second && pos->second != sock) {
|
||||
side_taken = 0;
|
||||
for(pos = positions_.begin(); pos != positions_.end(); ++pos, ++side_taken) {
|
||||
if(pos->first->values["controller"] == "network" &&
|
||||
pos->first->values["taken"] != "yes") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//does the client already own the side, and is just updating
|
||||
//it, or is it taking a vacant slot?
|
||||
const bool update_only = pos->second == sock;
|
||||
if(pos == positions_.end()) {
|
||||
config response;
|
||||
response.values["failed"] = "yes";
|
||||
network::send_data(response,sock);
|
||||
return;
|
||||
}
|
||||
|
||||
//broadcast to everyone the new game status
|
||||
pos->first->values["controller"] = "network";
|
||||
pos->first->values["taken"] = "yes";
|
||||
pos->first->values["description"] = cfg["description"];
|
||||
pos->first->values["name"] = cfg["name"];
|
||||
pos->first->values["type"] = cfg["type"];
|
||||
pos->first->values["recruit"] = cfg["recruit"];
|
||||
pos->first->values["music"] = cfg["music"];
|
||||
pos->first->values["terrain_liked"] = cfg["terrain_liked"];
|
||||
pos->second = sock;
|
||||
network::send_data(*level_);
|
||||
|
||||
std::cerr << "sent player data\n";
|
||||
|
||||
//send a reply telling the client they have secured
|
||||
//the side they asked for
|
||||
std::stringstream side;
|
||||
side << (side_taken+1);
|
||||
config reply;
|
||||
reply.values["side_secured"] = side.str();
|
||||
std::cerr << "going to send data...\n";
|
||||
network::send_data(reply,sock);
|
||||
|
||||
// Add to combo list
|
||||
add_player(cfg["description"]);
|
||||
} else {
|
||||
config response;
|
||||
response.values["failed"] = "yes";
|
||||
network::send_data(response,sock);
|
||||
config reassign;
|
||||
config& cfg = reassign.add_child("reassign_side");
|
||||
cfg["from"] = cfg["side"];
|
||||
cfg["to"] = lexical_cast<std::string>(side_taken+1);
|
||||
network::send_data(reassign,sock);
|
||||
}
|
||||
|
||||
std::cerr << "client has taken a valid position\n";
|
||||
|
||||
//does the client already own the side, and is just updating
|
||||
//it, or is it taking a vacant slot?
|
||||
const bool update_only = pos->second == sock;
|
||||
|
||||
//broadcast to everyone the new game status
|
||||
pos->first->values["controller"] = "network";
|
||||
pos->first->values["taken"] = "yes";
|
||||
|
||||
if(cfg["description"].empty() == false) {
|
||||
pos->first->values["description"] = cfg["description"];
|
||||
}
|
||||
|
||||
if(cfg["name"].empty() == false) {
|
||||
pos->first->values["name"] = cfg["name"];
|
||||
}
|
||||
|
||||
if(cfg["type"].empty() == false) {
|
||||
pos->first->values["type"] = cfg["type"];
|
||||
}
|
||||
|
||||
if(cfg["recruit"].empty() == false) {
|
||||
pos->first->values["recruit"] = cfg["recruit"];
|
||||
}
|
||||
|
||||
if(cfg["music"].empty() == false) {
|
||||
pos->first->values["music"] = cfg["music"];
|
||||
}
|
||||
|
||||
if(cfg["terrain_liked"].empty() == false) {
|
||||
pos->first->values["terrain_liked"] = cfg["terrain_liked"];
|
||||
}
|
||||
|
||||
pos->second = sock;
|
||||
network::send_data(*level_);
|
||||
|
||||
std::cerr << "sent player data\n";
|
||||
|
||||
//send a reply telling the client they have secured
|
||||
//the side they asked for
|
||||
std::stringstream side;
|
||||
side << (side_taken+1);
|
||||
config reply;
|
||||
reply.values["side_secured"] = side.str();
|
||||
std::cerr << "going to send data...\n";
|
||||
network::send_data(reply,sock);
|
||||
|
||||
// Add to combo list
|
||||
add_player(cfg["description"]);
|
||||
} else {
|
||||
std::cerr << "tried to take illegal side: " << side_taken << "\n";
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ RESULT enter(display& disp, config& game_data, const config& terrain_data, dialo
|
|||
chat_textbox.scroll_to_bottom();
|
||||
|
||||
std::vector<std::string> options;
|
||||
std::vector<bool> game_vacant_slots, game_observers;
|
||||
|
||||
const config* const gamelist = game_data.child("gamelist");
|
||||
|
||||
|
@ -144,6 +145,8 @@ RESULT enter(display& disp, config& game_data, const config& terrain_data, dialo
|
|||
}
|
||||
|
||||
options.push_back(str.str());
|
||||
game_vacant_slots.push_back(slots != "" && slots != "0");
|
||||
game_observers.push_back((**i.first)["observer"] != "no");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,17 +156,25 @@ RESULT enter(display& disp, config& game_data, const config& terrain_data, dialo
|
|||
}
|
||||
|
||||
gui::menu games_menu(disp,options);
|
||||
gui::button observe_game(disp,string_table["observe_game"]);
|
||||
gui::button join_game(disp,string_table["join_game"]);
|
||||
gui::button new_game(disp,string_table["create_new_game"]);
|
||||
gui::button quit_game(disp,string_table["quit_button"]);
|
||||
|
||||
if(dlg != NULL) {
|
||||
observe_game.hide();
|
||||
join_game.hide();
|
||||
new_game.hide();
|
||||
quit_game.hide();
|
||||
}
|
||||
|
||||
if(!games_available) {
|
||||
if(games_menu.selection() >= 0 && games_menu.selection() < int(game_vacant_slots.size())) {
|
||||
assert(game_vacant_slots.size() == game_observers.size());
|
||||
|
||||
join_game.hide(!game_vacant_slots[games_menu.selection()]);
|
||||
observe_game.hide(!game_observers[games_menu.selection()]);
|
||||
} else {
|
||||
observe_game.hide();
|
||||
join_game.hide();
|
||||
}
|
||||
|
||||
|
@ -217,8 +228,9 @@ RESULT enter(display& disp, config& game_data, const config& terrain_data, dialo
|
|||
|
||||
update_rect(xscale(disp,19),yscale(disp,23),xscale(disp,832),yscale(disp,520));
|
||||
join_game.set_location(xscale(disp,19),yscale(disp,545));
|
||||
new_game.set_location(xscale(disp,19)+join_game.width()+5,yscale(disp,545));
|
||||
quit_game.set_location(xscale(disp,19)+join_game.width()+5+new_game.width()+5,yscale(disp,545));
|
||||
observe_game.set_location(join_game.location().x + join_game.location().w + 5,yscale(disp,545));
|
||||
new_game.set_location(observe_game.location().x + observe_game.location().w + 5,yscale(disp,545));
|
||||
quit_game.set_location(new_game.location().x + new_game.location().w + 5,yscale(disp,545));
|
||||
message_entry.set_location(xscale(disp,19),yscale(disp,725));
|
||||
message_entry.set_width(xscale(disp,832));
|
||||
|
||||
|
@ -241,14 +253,19 @@ RESULT enter(display& disp, config& game_data, const config& terrain_data, dialo
|
|||
games_menu.process(mousex,mousey,left_button,
|
||||
key[SDLK_UP],key[SDLK_DOWN],
|
||||
key[SDLK_PAGEUP],key[SDLK_PAGEDOWN]);
|
||||
|
||||
if(games_menu.selection() >= 0 && games_menu.selection() < int(game_vacant_slots.size())) {
|
||||
join_game.hide(!game_vacant_slots[games_menu.selection()]);
|
||||
observe_game.hide(!game_observers[games_menu.selection()]);
|
||||
}
|
||||
}
|
||||
|
||||
users_menu.process(mousex,mousey,left_button,
|
||||
key[SDLK_UP],key[SDLK_DOWN],
|
||||
key[SDLK_PAGEUP],key[SDLK_PAGEDOWN]);
|
||||
|
||||
if(games_available &&
|
||||
(join_game.process(mousex,mousey,left_button) || games_menu.double_clicked())) {
|
||||
const bool observe = observe_game.pressed();
|
||||
if(games_available && (observe || join_game.pressed() || games_menu.double_clicked())) {
|
||||
const size_t index = size_t(games_menu.selection());
|
||||
const config::const_child_itors i = gamelist->child_range("game");
|
||||
assert(index < size_t(i.second - i.first));
|
||||
|
@ -258,10 +275,10 @@ RESULT enter(display& disp, config& game_data, const config& terrain_data, dialo
|
|||
config& join = response.add_child("join");
|
||||
join["id"] = id;
|
||||
network::send_data(response);
|
||||
return JOIN;
|
||||
return observe ? OBSERVE : JOIN;
|
||||
}
|
||||
|
||||
if(dlg == NULL && new_game.process(mousex,mousey,left_button)) {
|
||||
if(dlg == NULL && new_game.pressed()) {
|
||||
return CREATE;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
///allows players to chat, create games, and join games.
|
||||
namespace lobby {
|
||||
|
||||
enum RESULT { QUIT, CREATE, JOIN, CONTINUE };
|
||||
enum RESULT { QUIT, CREATE, JOIN, OBSERVE, CONTINUE };
|
||||
|
||||
///interface for an interactive dialog that is displayed while lobby user lists
|
||||
///and lobby chat continue
|
||||
|
|
|
@ -112,6 +112,7 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
game_state& state_of_game,
|
||||
const std::vector<config*>& story)
|
||||
{
|
||||
const int ticks = SDL_GetTicks();
|
||||
std::cerr << "in play_level()...\n";
|
||||
|
||||
//if the entire scenario should be randomly generated
|
||||
|
@ -146,6 +147,8 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
state_of_game.starting_pos = new_level;
|
||||
}
|
||||
|
||||
std::cerr << "generated map " << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
const statistics::scenario_context statistics_context(translate_string_default((*level)["id"],(*level)["name"]));
|
||||
|
||||
const int num_turns = atoi(level->values["turns"].c_str());
|
||||
|
@ -153,6 +156,8 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
|
||||
gamemap map(game_config,map_data);
|
||||
|
||||
std::cerr << "created objects... " << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
CKey key;
|
||||
unit_map units;
|
||||
|
||||
|
@ -175,6 +180,7 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
}
|
||||
|
||||
std::cerr << "initializing teams..." << unit_cfg.size() << "\n";;
|
||||
std::cerr << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
for(config::child_list::const_iterator ui = unit_cfg.begin(); ui != unit_cfg.end(); ++ui) {
|
||||
std::cerr << "initializing team...\n";
|
||||
|
@ -268,6 +274,8 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
}
|
||||
}
|
||||
|
||||
std::cerr << "initialized teams... " << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
const config* theme_cfg = NULL;
|
||||
if((*level)["theme"] != "") {
|
||||
theme_cfg = game_config.find_child("theme","name",(*level)["theme"]);
|
||||
|
@ -277,14 +285,19 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
theme_cfg = game_config.find_child("theme","name",preferences::theme());
|
||||
}
|
||||
|
||||
std::cerr << "initializing display... " << (SDL_GetTicks() - ticks) << "\n";
|
||||
const config dummy_cfg;
|
||||
display gui(units,video,map,status,teams,theme_cfg != NULL ? *theme_cfg : dummy_cfg, game_config);
|
||||
|
||||
std::cerr << "done initializing display... " << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
//object that will make sure that labels are removed at the end of the scenario
|
||||
const font::floating_label_manager labels_manager;
|
||||
|
||||
gui.labels().read(*level);
|
||||
|
||||
std::cerr << "a... " << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
if(first_human_team != -1) {
|
||||
gui.set_team(first_human_team);
|
||||
}
|
||||
|
@ -292,6 +305,8 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
const preferences::display_manager prefs_disp_manager(&gui);
|
||||
const tooltips::manager tooltips_manager(gui);
|
||||
|
||||
std::cerr << "b... " << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
if(recorder.skipping() == false) {
|
||||
for(std::vector<config*>::const_iterator story_i = story.begin();
|
||||
story_i != story.end(); ++story_i) {
|
||||
|
@ -301,14 +316,20 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
show_map_scene(gui,*level);
|
||||
}
|
||||
|
||||
std::cerr << "c... " << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
const std::string& music = level->values["music"];
|
||||
if(music != "") {
|
||||
sound::play_music(music);
|
||||
}
|
||||
|
||||
std::cerr << "d... " << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
victory_conditions::set_victory_when_enemies_defeated(
|
||||
(*level)["victory_when_enemies_defeated"] != "no");
|
||||
|
||||
std::cerr << "initializing events manager... " << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
game_events::manager events_manager(*level,gui,map,units,teams,
|
||||
state_of_game,status,gameinfo);
|
||||
|
||||
|
@ -322,17 +343,23 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
|
||||
turn_info::floating_textbox textbox_info;
|
||||
|
||||
std::cerr << "entering try... " << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
try {
|
||||
gui.begin_game();
|
||||
gui.adjust_colours(0,0,0);
|
||||
game_events::fire("prestart");
|
||||
|
||||
std::cerr << "scrolling... " << (SDL_GetTicks() - ticks) << "\n";
|
||||
if(first_human_team != -1) {
|
||||
clear_shroud(gui,status,map,gameinfo,units,teams,first_human_team);
|
||||
std::cerr << "b " << (SDL_GetTicks() - ticks) << "\n";
|
||||
gui.scroll_to_tile(map.starting_position(first_human_team+1).x,map.starting_position(first_human_team+1).y,display::WARP);
|
||||
std::cerr << "c " << (SDL_GetTicks() - ticks) << "\n";
|
||||
}
|
||||
|
||||
gui.scroll_to_tile(map.starting_position(1).x,map.starting_position(1).y,display::WARP);
|
||||
std::cerr << "done scrolling... " << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
bool replaying = (recorder.at_end() == false);
|
||||
|
||||
|
@ -345,6 +372,7 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
}
|
||||
|
||||
std::cerr << "starting main loop\n";
|
||||
std::cerr << (SDL_GetTicks() - ticks) << "\n";
|
||||
|
||||
std::deque<config> data_backlog;
|
||||
|
||||
|
|
|
@ -242,7 +242,8 @@ report generate_report(TYPE type, const gamemap& map, const unit_map& units,
|
|||
break;
|
||||
}
|
||||
case UPKEEP: {
|
||||
str << team_upkeep(units,current_side);
|
||||
const team_data data = calculate_team_data(current_team,current_side,units);
|
||||
str << data.expenses << " (" << data.upkeep << ")";
|
||||
break;
|
||||
}
|
||||
case EXPENSES: {
|
||||
|
|
|
@ -111,10 +111,37 @@ bool game::take_side(network::connection player, const config& cfg)
|
|||
|
||||
const std::string& side = cfg["side"];
|
||||
|
||||
//if the player is already on a side or the side is already taken
|
||||
if(sides_.count(player) || sides_taken_.count(side))
|
||||
//if the player is already on a side
|
||||
if(sides_.count(player))
|
||||
return false;
|
||||
|
||||
//if the side is already taken, see if we can give the player
|
||||
//another side instead
|
||||
if(sides_taken_.count(side)) {
|
||||
std::cerr << "side '" << side << "' taken, searching for alternative side\n";
|
||||
const config::child_list& sides = level_.get_children("side");
|
||||
for(config::child_list::const_iterator i = sides.begin(); i != sides.end(); ++i) {
|
||||
if((**i)["controller"] == "network" && sides_taken_.count((**i)["side"]) == 0) {
|
||||
config new_cfg = cfg;
|
||||
new_cfg["side"] = (**i)["side"];
|
||||
|
||||
const bool res = take_side(player,new_cfg);
|
||||
|
||||
//if there's another side available, then tell the player that they've
|
||||
//had their side reassigned
|
||||
if(res) {
|
||||
config response;
|
||||
config& reassign = response.add_child("reassign_side");
|
||||
reassign["from"] = cfg["side"];
|
||||
reassign["to"] = new_cfg["side"];
|
||||
network::send_data(response,player);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sides_[player] = side;
|
||||
sides_taken_.insert(side);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue