mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-11 17:28:18 +00:00
made it so quitting from a networked multiplayer game on a server...
...takes the player back to the lobby
This commit is contained in:
parent
d89efc6a73
commit
df23cfa795
@ -167,7 +167,7 @@
|
||||
[multiplayer_side]
|
||||
name=Orcs
|
||||
type=Orcish Warlord
|
||||
recruit=Orcish Grunt,Troll Whelp,Wolf Rider,Orcish Archer
|
||||
recruit=Orcish Grunt,Troll Whelp,Wolf Rider,Orcish Archer,Orcish Assassin
|
||||
recruitment_pattern=fighter,fighter,archer,scout
|
||||
[/multiplayer_side]
|
||||
|
||||
@ -181,6 +181,6 @@
|
||||
[multiplayer_side]
|
||||
name=Undead
|
||||
type=Lich
|
||||
recruit=Skeleton,Skeleton Archer,Walking Corpse,Ghost,Blood Bat,Dark Adept
|
||||
recruit=Skeleton,Skeleton Archer,Walking Corpse,Ghost,Vampire Bat,Dark Adept
|
||||
recruitment_pattern=scout,fighter,fighter,archer
|
||||
[/multiplayer_side]
|
||||
|
@ -1,176 +1,3 @@
|
||||
[test]
|
||||
name=Isles Of The Damned
|
||||
map=jzmap
|
||||
turns=32
|
||||
id=test
|
||||
objectives="
|
||||
Victory:
|
||||
@Defeat both enemy leaders
|
||||
@Resist until the end of the turns
|
||||
Defeat:
|
||||
#Death of Konrad
|
||||
#Death of Habwa"
|
||||
{DAWN}
|
||||
{MORNING}
|
||||
{AFTERNOON}
|
||||
{DUSK}
|
||||
{FIRST_WATCH}
|
||||
{SECOND_WATCH}
|
||||
[side]
|
||||
type=Commander
|
||||
description=Konrad
|
||||
side=1
|
||||
canrecruit=1
|
||||
controller=human
|
||||
gold=350
|
||||
recruit=Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Shaman,Merman
|
||||
enemy=2
|
||||
[/side]
|
||||
[side]
|
||||
type=Lich
|
||||
description=Urug-Telfar
|
||||
side=2
|
||||
canrecruit=1
|
||||
recruit=Skeleton,Chocobone,Bone Shooter,Dark Adept,Mermen
|
||||
recruitment_pattern=fighter,scout,fighter,fighter,scout
|
||||
gold=200
|
||||
enemy=1
|
||||
[/side]
|
||||
[side]
|
||||
type=Lich
|
||||
description=Ga'hal
|
||||
side=3
|
||||
canrecruit=1
|
||||
recruit=Skeleton
|
||||
recruitment_pattern=fighter
|
||||
gold=50
|
||||
enemy=1
|
||||
[/side]
|
||||
[item]
|
||||
x=24
|
||||
y=32
|
||||
image=item-holywater.png
|
||||
[/item]
|
||||
[item]
|
||||
x=28
|
||||
y=2
|
||||
image=merman-king.png
|
||||
[/item]
|
||||
[item]
|
||||
x=28
|
||||
y=2
|
||||
image=misc/cage.png
|
||||
[/item]
|
||||
[event]
|
||||
name=moveto
|
||||
first_time_only=no
|
||||
[filter]
|
||||
side=1
|
||||
x=24
|
||||
y=32
|
||||
[/filter]
|
||||
[object]
|
||||
id=object7_holywater
|
||||
name=Holy Water
|
||||
image=item-holywater.png
|
||||
duration=level
|
||||
description=This water will make close range weapons holy.
|
||||
cannot_use_message=I am not suited to using this item! Let another take it.
|
||||
[effect]
|
||||
apply_to=attack
|
||||
range=short
|
||||
set_type=holy
|
||||
[/effect]
|
||||
[/object]
|
||||
[/event]
|
||||
[event]
|
||||
name=moveto
|
||||
[removeitem]
|
||||
[/removeitem]
|
||||
[filter]
|
||||
side=1
|
||||
x=28
|
||||
y=2
|
||||
[/filter]
|
||||
[unit]
|
||||
description=Habwa
|
||||
side=1
|
||||
type=Merman Lord
|
||||
x=28
|
||||
y=3
|
||||
[/unit]
|
||||
[unit]
|
||||
side=1
|
||||
type=Merman
|
||||
x=28
|
||||
y=1
|
||||
[/unit]
|
||||
[unit]
|
||||
side=1
|
||||
type=Merman
|
||||
x=29
|
||||
y=2
|
||||
[/unit]
|
||||
[message]
|
||||
id=msgIOFD_1
|
||||
description=Habwa
|
||||
message="Thank you for freeing me. I have been here for so long, ever sence the Lichen took over my beutiful islands."
|
||||
[/message]
|
||||
[message]
|
||||
id=msgIOFD_2
|
||||
description=Konrad
|
||||
message="Together we can reclaim your islands."
|
||||
[/message]
|
||||
[message]
|
||||
id=msgIOFD_3
|
||||
description=Habwa
|
||||
message="If succesfull your h
|
||||
elp will not go unrecognised."
|
||||
[/message]
|
||||
[/event]
|
||||
[event]
|
||||
name=time over
|
||||
[message]
|
||||
id=msgIOFD_4
|
||||
description=Habwa
|
||||
message="They are to strong for us, we must retreat."
|
||||
[/message]
|
||||
[message]
|
||||
id=msgIOFD_5
|
||||
description=Konrad
|
||||
message="I fear you are right. Good luck in your future journies Habwa."
|
||||
[/message]
|
||||
[message]
|
||||
id=msgIOFD_6
|
||||
description=Habwa
|
||||
message="And to you Konrad, may your travels be free from danger."
|
||||
[/message]
|
||||
[endlevel]
|
||||
result=victory
|
||||
[/endlevel]
|
||||
[/event]
|
||||
[event]
|
||||
name=victory
|
||||
[message]
|
||||
id=msgIOFD_7
|
||||
description=Habwa
|
||||
message="They were strong, but I have my kingdom once again."
|
||||
[/message]
|
||||
[message]
|
||||
id=msgIOFD_8
|
||||
description=Konrad
|
||||
message="I am gald to have been of service to you, Lord Habwa."
|
||||
[/message]
|
||||
[message]
|
||||
id=msgIOFD_9
|
||||
description=Habwa
|
||||
message="As I had told you, your help has not gone unrecognized."
|
||||
[/message]
|
||||
# Konrad should get ring of regeneration
|
||||
[/event]
|
||||
[/test]
|
||||
|
||||
[a]
|
||||
[test]
|
||||
name=Scenario 1: The Elves Besieged
|
||||
map=map-test
|
||||
@ -205,4 +32,3 @@ elp will not go unrecognised."
|
||||
enemy=1
|
||||
[/side]
|
||||
[/test]
|
||||
[/a]
|
||||
|
@ -20,6 +20,9 @@ by their skill with both sword and bow.
|
||||
|
||||
The Elves are deft of foot, and fight best
|
||||
in the forest."
|
||||
|
||||
get_hit_sound=groan.wav
|
||||
|
||||
[attack]
|
||||
name=sword
|
||||
type=blade
|
||||
|
@ -21,13 +21,11 @@ unit_description="The orcish crossbow tries to compensate his lack of skill with
|
||||
time=-100
|
||||
sound=firearrow.wav
|
||||
[/sound]
|
||||
|
||||
[sound]
|
||||
time=0
|
||||
sound=arrow-hit.wav
|
||||
sound_miss=arrow-miss.wav
|
||||
[/sound]
|
||||
|
||||
[missile_frame]
|
||||
begin=-100
|
||||
end=0
|
||||
|
@ -1739,6 +1739,10 @@ bool display::unit_attack_ranged(const gamemap::location& a,
|
||||
const std::vector<attack_type::sfx>& sounds = attack.sound_effects();
|
||||
std::vector<attack_type::sfx>::const_iterator sfx_it = sounds.begin();
|
||||
|
||||
const std::string& hit_sound = def->second.type().get_hit_sound();
|
||||
bool played_hit_sound = (hit_sound == "" || hit_sound == "null");
|
||||
const int play_hit_sound_at = 0;
|
||||
|
||||
const bool hits = damage > 0;
|
||||
const int begin_at = attack.get_first_frame();
|
||||
const int end_at = maximum((damage+1)*time_resolution+missile_impact,
|
||||
@ -1778,6 +1782,11 @@ bool display::unit_attack_ranged(const gamemap::location& a,
|
||||
++sfx_it;
|
||||
}
|
||||
|
||||
if(hits && !played_hit_sound && i >= play_hit_sound_at) {
|
||||
sound::play_sound(hit_sound);
|
||||
played_hit_sound = true;
|
||||
}
|
||||
|
||||
const std::string* unit_image = attack.get_frame(i);
|
||||
|
||||
if(unit_image == NULL) {
|
||||
@ -1869,6 +1878,14 @@ void display::unit_die(const gamemap::location& loc, SDL_Surface* image)
|
||||
if(update_locked() || shrouded(loc.x,loc.y))
|
||||
return;
|
||||
|
||||
const unit_map::const_iterator u = units_.find(loc);
|
||||
assert(u != units_.end());
|
||||
|
||||
const std::string& die_sound = u->second.type().die_sound();
|
||||
if(die_sound != "" && die_sound != "null") {
|
||||
sound::play_sound(die_sound);
|
||||
}
|
||||
|
||||
const int frame_time = 30;
|
||||
int ticks = SDL_GetTicks();
|
||||
|
||||
@ -1953,6 +1970,10 @@ bool display::unit_attack(const gamemap::location& a,
|
||||
const std::vector<attack_type::sfx>& sounds = attack.sound_effects();
|
||||
std::vector<attack_type::sfx>::const_iterator sfx_it = sounds.begin();
|
||||
|
||||
const std::string& hit_sound = def->second.type().get_hit_sound();
|
||||
bool played_hit_sound = (hit_sound == "" || hit_sound == "null");
|
||||
const int play_hit_sound_at = 0;
|
||||
|
||||
const int time_resolution = 20;
|
||||
const int acceleration = turbo() ? 5 : 1;
|
||||
|
||||
@ -1994,6 +2015,11 @@ bool display::unit_attack(const gamemap::location& a,
|
||||
++sfx_it;
|
||||
}
|
||||
|
||||
if(hits && !played_hit_sound && i >= play_hit_sound_at) {
|
||||
sound::play_sound(hit_sound);
|
||||
played_hit_sound = true;
|
||||
}
|
||||
|
||||
for(int j = 0; j != 6; ++j) {
|
||||
draw_tile(update_tiles[j].x,update_tiles[j].y);
|
||||
}
|
||||
|
@ -26,6 +26,15 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
network_game_manager::~network_game_manager()
|
||||
{
|
||||
if(network::nconnections() > 0) {
|
||||
config cfg;
|
||||
cfg.add_child("leave_game");
|
||||
network::send_data(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class connection_acceptor : public gui::dialog_action
|
||||
@ -232,6 +241,9 @@ void play_multiplayer(display& disp, game_data& units_data, config cfg,
|
||||
{
|
||||
log_scope("play multiplayer");
|
||||
|
||||
//ensure we send a close game message to the server when we are done
|
||||
const network_game_manager game_manager = network_game_manager();
|
||||
|
||||
std::vector<std::string> options;
|
||||
std::vector<config*>& levels = cfg.children["multiplayer"];
|
||||
std::map<int,std::string> res_to_id;
|
||||
|
@ -19,6 +19,10 @@
|
||||
#include "unit_types.hpp"
|
||||
#include "video.hpp"
|
||||
|
||||
struct network_game_manager {
|
||||
~network_game_manager();
|
||||
};
|
||||
|
||||
void play_multiplayer_client(display& disp, game_data& units_data,
|
||||
config& cfg, game_state& state);
|
||||
|
||||
|
@ -99,6 +99,18 @@ void check_response(network::connection res, const config& data)
|
||||
}
|
||||
}
|
||||
|
||||
void receive_gamelist(config& data)
|
||||
{
|
||||
for(;;) {
|
||||
const network::connection res = network::receive_data(data,0,3000);
|
||||
check_response(res,data);
|
||||
|
||||
if(data.child("gamelist")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class wait_for_start : public gui::dialog_action
|
||||
{
|
||||
public:
|
||||
@ -167,6 +179,8 @@ void play_multiplayer_client(display& disp, game_data& units_data, config& cfg,
|
||||
+ "' while you are using version'" + game_config::version);
|
||||
}
|
||||
|
||||
bool logged_in = false;
|
||||
|
||||
//if we got a direction to login
|
||||
if(data.child("mustlogin")) {
|
||||
|
||||
@ -196,133 +210,145 @@ void play_multiplayer_client(display& disp, game_data& units_data, config& cfg,
|
||||
|
||||
error = data.child("error");
|
||||
} while(error != NULL);
|
||||
|
||||
logged_in = true;
|
||||
}
|
||||
|
||||
//if we got a gamelist back - otherwise we have
|
||||
//got a description of the game back
|
||||
const config* const gamelist = data.child("gamelist");
|
||||
if(gamelist != NULL) {
|
||||
config game_data = data;
|
||||
const lobby::RESULT res = lobby::enter(disp,game_data);
|
||||
switch(res) {
|
||||
case lobby::QUIT: {
|
||||
return;
|
||||
}
|
||||
case lobby::CREATE: {
|
||||
std::cerr << "playing multiplayer...\n";
|
||||
play_multiplayer(disp,units_data,cfg,state,false);
|
||||
return;
|
||||
}
|
||||
case lobby::JOIN: {
|
||||
break;
|
||||
}
|
||||
for(bool first_time = true; logged_in && network::nconnections() > 0;
|
||||
first_time = false) {
|
||||
|
||||
if(!first_time) {
|
||||
receive_gamelist(data);
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
data_res = network::receive_data(sides,0,5000);
|
||||
check_response(data_res,data);
|
||||
|
||||
//if we have got valid side data
|
||||
if(sides.child("gamelist") == NULL) {
|
||||
break;
|
||||
//if we got a gamelist back - otherwise we have
|
||||
//got a description of the game back
|
||||
const config* const gamelist = data.child("gamelist");
|
||||
if(gamelist != NULL) {
|
||||
config game_data = data;
|
||||
const lobby::RESULT res = lobby::enter(disp,game_data);
|
||||
switch(res) {
|
||||
case lobby::QUIT: {
|
||||
return;
|
||||
}
|
||||
case lobby::CREATE: {
|
||||
play_multiplayer(disp,units_data,cfg,state,false);
|
||||
continue;
|
||||
}
|
||||
case lobby::JOIN: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
data_res = network::receive_data(sides,0,5000);
|
||||
check_response(data_res,data);
|
||||
|
||||
//if we have got valid side data
|
||||
if(sides.child("gamelist") == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sides = data;
|
||||
}
|
||||
} else {
|
||||
sides = data;
|
||||
}
|
||||
|
||||
std::map<int,int> choice_map;
|
||||
std::vector<std::string> choices;
|
||||
choices.push_back(string_table["observer"]);
|
||||
|
||||
std::vector<config*>& sides_list = sides.children["side"];
|
||||
for(std::vector<config*>::iterator s = sides_list.begin();
|
||||
s != sides_list.end(); ++s) {
|
||||
if((*s)->values["controller"] == "network" &&
|
||||
(*s)->values["taken"] != "yes") {
|
||||
choice_map[choices.size()] = 1 + s - sides_list.begin();
|
||||
choices.push_back((*s)->values["name"] + " - " +
|
||||
(*s)->values["type"]);
|
||||
}
|
||||
}
|
||||
|
||||
const int choice = gui::show_dialog(disp,NULL,"","Choose side:",
|
||||
gui::OK_CANCEL,&choices);
|
||||
if(choice < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int team_num = choice_map[choice];
|
||||
const bool observer = choice == 0;
|
||||
|
||||
//send our choice of team to the server
|
||||
if(!observer) {
|
||||
config response;
|
||||
std::stringstream stream;
|
||||
stream << team_num;
|
||||
response["side"] = stream.str();
|
||||
response["description"] = preferences::login();
|
||||
network::send_data(response);
|
||||
}
|
||||
|
||||
wait_for_start waiter(sides);
|
||||
const int dialog_res = gui::show_dialog(disp,NULL,"",
|
||||
"Waiting for game to start...",
|
||||
gui::CANCEL_ONLY,NULL,NULL,"",NULL,&waiter);
|
||||
if(dialog_res != wait_for_start::START_GAME) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!observer && !waiter.got_side) {
|
||||
throw network::error("Choice of team unavailable.");
|
||||
}
|
||||
|
||||
//we want to make the network/human players look right from our
|
||||
//perspective
|
||||
{
|
||||
//ensure we send a close game message to the server when we are done
|
||||
const network_game_manager game_manager = network_game_manager();
|
||||
|
||||
std::map<int,int> choice_map;
|
||||
std::vector<std::string> choices;
|
||||
choices.push_back(string_table["observer"]);
|
||||
|
||||
std::vector<config*>& sides_list = sides.children["side"];
|
||||
for(std::vector<config*>::iterator side = sides_list.begin();
|
||||
side != sides_list.end(); ++side) {
|
||||
string_map& values = (*side)->values;
|
||||
if(team_num-1 == side - sides_list.begin())
|
||||
values["controller"] = "human";
|
||||
else
|
||||
values["controller"] = "network";
|
||||
}
|
||||
}
|
||||
|
||||
//any replay data is only temporary and should be removed from
|
||||
//the level data in case we want to save the game later
|
||||
config* const replay_data = sides.child("replay");
|
||||
config replay_data_store;
|
||||
if(replay_data != NULL) {
|
||||
replay_data_store = *replay_data;
|
||||
std::cerr << "setting replay\n";
|
||||
recorder = replay(replay_data_store);
|
||||
if(!recorder.empty()) {
|
||||
const int res = gui::show_dialog(disp,NULL,
|
||||
"", string_table["replay_game_message"],
|
||||
gui::YES_NO);
|
||||
//if yes, then show the replay, otherwise
|
||||
//skip showing the replay
|
||||
if(res == 0) {
|
||||
recorder.set_skip(0);
|
||||
} else {
|
||||
std::cerr << "skipping...\n";
|
||||
recorder.set_skip(-1);
|
||||
for(std::vector<config*>::iterator s = sides_list.begin();
|
||||
s != sides_list.end(); ++s) {
|
||||
if((*s)->values["controller"] == "network" &&
|
||||
(*s)->values["taken"] != "yes") {
|
||||
choice_map[choices.size()] = 1 + s - sides_list.begin();
|
||||
choices.push_back((*s)->values["name"] + " - " +
|
||||
(*s)->values["type"]);
|
||||
}
|
||||
}
|
||||
|
||||
sides.children["replay"].clear();
|
||||
|
||||
const int choice = gui::show_dialog(disp,NULL,"","Choose side:",
|
||||
gui::OK_CANCEL,&choices);
|
||||
if(choice < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const int team_num = choice_map[choice];
|
||||
const bool observer = choice == 0;
|
||||
|
||||
//send our choice of team to the server
|
||||
if(!observer) {
|
||||
config response;
|
||||
std::stringstream stream;
|
||||
stream << team_num;
|
||||
response["side"] = stream.str();
|
||||
response["description"] = preferences::login();
|
||||
network::send_data(response);
|
||||
}
|
||||
|
||||
wait_for_start waiter(sides);
|
||||
const int dialog_res = gui::show_dialog(disp,NULL,"",
|
||||
"Waiting for game to start...",
|
||||
gui::CANCEL_ONLY,NULL,NULL,"",NULL,&waiter);
|
||||
if(dialog_res != wait_for_start::START_GAME) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!observer && !waiter.got_side) {
|
||||
throw network::error("Choice of team unavailable.");
|
||||
}
|
||||
|
||||
//we want to make the network/human players look right from our
|
||||
//perspective
|
||||
{
|
||||
std::vector<config*>& sides_list = sides.children["side"];
|
||||
for(std::vector<config*>::iterator side = sides_list.begin();
|
||||
side != sides_list.end(); ++side) {
|
||||
string_map& values = (*side)->values;
|
||||
if(team_num-1 == side - sides_list.begin())
|
||||
values["controller"] = "human";
|
||||
else
|
||||
values["controller"] = "network";
|
||||
}
|
||||
}
|
||||
|
||||
//any replay data is only temporary and should be removed from
|
||||
//the level data in case we want to save the game later
|
||||
config* const replay_data = sides.child("replay");
|
||||
config replay_data_store;
|
||||
if(replay_data != NULL) {
|
||||
replay_data_store = *replay_data;
|
||||
std::cerr << "setting replay\n";
|
||||
recorder = replay(replay_data_store);
|
||||
if(!recorder.empty()) {
|
||||
const int res = gui::show_dialog(disp,NULL,
|
||||
"", string_table["replay_game_message"],
|
||||
gui::YES_NO);
|
||||
//if yes, then show the replay, otherwise
|
||||
//skip showing the replay
|
||||
if(res == 0) {
|
||||
recorder.set_skip(0);
|
||||
} else {
|
||||
std::cerr << "skipping...\n";
|
||||
recorder.set_skip(-1);
|
||||
}
|
||||
}
|
||||
|
||||
sides.children["replay"].clear();
|
||||
}
|
||||
|
||||
std::cerr << "starting game\n";
|
||||
|
||||
state.starting_pos = sides;
|
||||
|
||||
recorder.set_save_info(state);
|
||||
|
||||
std::vector<config*> story;
|
||||
play_level(units_data,cfg,&sides,disp.video(),state,story);
|
||||
recorder.clear();
|
||||
}
|
||||
|
||||
std::cerr << "starting game\n";
|
||||
|
||||
state.starting_pos = sides;
|
||||
|
||||
recorder.set_save_info(state);
|
||||
|
||||
std::vector<config*> story;
|
||||
play_level(units_data,cfg,&sides,disp.video(),state,story);
|
||||
recorder.clear();
|
||||
}
|
||||
|
@ -41,10 +41,12 @@ manager::manager() : free_(true)
|
||||
|
||||
manager::~manager()
|
||||
{
|
||||
disconnect();
|
||||
SDLNet_FreeSocketSet(socket_set);
|
||||
socket_set = 0;
|
||||
SDLNet_Quit();
|
||||
if(free_) {
|
||||
disconnect();
|
||||
SDLNet_FreeSocketSet(socket_set);
|
||||
socket_set = 0;
|
||||
SDLNet_Quit();
|
||||
}
|
||||
}
|
||||
|
||||
server_manager::server_manager(int port, bool create_server)
|
||||
|
@ -212,6 +212,10 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
||||
for(;;) {
|
||||
network::connection res =
|
||||
network::receive_data(cfg);
|
||||
if(res && cfg.child("leave_game")) {
|
||||
throw network::error("");
|
||||
}
|
||||
|
||||
if(res && cfg.children["turn"].empty() == false) {
|
||||
break;
|
||||
}
|
||||
@ -352,6 +356,10 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& terrain_config,
|
||||
return QUIT;
|
||||
}
|
||||
catch(network::error& e) {
|
||||
if(e.socket) {
|
||||
e.disconnect();
|
||||
}
|
||||
|
||||
std::string label = string_table["multiplayer_save_name"];
|
||||
const int res = gui::show_dialog(gui,NULL,"",
|
||||
string_table["save_game_error"],
|
||||
|
@ -132,3 +132,9 @@ config* game::description()
|
||||
{
|
||||
return description_;
|
||||
}
|
||||
|
||||
void game::add_players(const game& other_game)
|
||||
{
|
||||
players_.insert(players_.end(),
|
||||
other_game.players_.begin(),other_game.players_.end());
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ public:
|
||||
void set_description(config* desc);
|
||||
config* description();
|
||||
|
||||
void add_players(const game& other_game);
|
||||
|
||||
private:
|
||||
static int id_num;
|
||||
int id_;
|
||||
|
@ -217,8 +217,44 @@ int main()
|
||||
}
|
||||
|
||||
if(data.child("start_game")) {
|
||||
std::cerr << "!! start_game: " << data.write() << "\n";
|
||||
g->start_game();
|
||||
} else if(data.child("leave_game")) {
|
||||
const bool needed = g->is_needed(sock);
|
||||
g->remove_player(sock);
|
||||
lobby_players.add_player(sock);
|
||||
|
||||
if(needed) {
|
||||
|
||||
//tell all other players the game is over,
|
||||
//because a needed player has left
|
||||
config cfg;
|
||||
cfg.add_child("leave_game");
|
||||
g->send_data(cfg);
|
||||
|
||||
//delete the game's description
|
||||
config* const gamelist =
|
||||
initial_response.child("gamelist");
|
||||
assert(gamelist != NULL);
|
||||
std::vector<config*>& vg =
|
||||
gamelist->children["game"];
|
||||
std::vector<config*>::iterator desc =
|
||||
std::find(vg.begin(),vg.end(),g->description());
|
||||
if(desc != vg.end()) {
|
||||
delete *desc;
|
||||
vg.erase(desc);
|
||||
}
|
||||
|
||||
//put the players back in the lobby and send
|
||||
//them the game list and user list again
|
||||
g->send_data(initial_response);
|
||||
lobby_players.add_players(*g);
|
||||
games.erase(g);
|
||||
}
|
||||
|
||||
//send the player who has quit the new game list
|
||||
network::send_data(initial_response,sock);
|
||||
|
||||
continue;
|
||||
} else if(data["side_secured"].empty() == false) {
|
||||
continue;
|
||||
} else if(data["failed"].empty() == false) {
|
||||
|
@ -40,7 +40,7 @@ manager::manager()
|
||||
Mix_OpenAudio(MIX_DEFAULT_FREQUENCY,MIX_DEFAULT_FORMAT,2,1024);
|
||||
if(res >= 0) {
|
||||
mix_ok = true;
|
||||
Mix_AllocateChannels(8);
|
||||
Mix_AllocateChannels(16);
|
||||
} else {
|
||||
mix_ok = false;
|
||||
std::cerr << "Could not initialize audio: " << SDL_GetError() << "\n";
|
||||
|
@ -456,6 +456,16 @@ const std::string& unit_type::unit_description() const
|
||||
return desc;
|
||||
}
|
||||
|
||||
const std::string& unit_type::get_hit_sound() const
|
||||
{
|
||||
return cfg_["get_hit_sound"];
|
||||
}
|
||||
|
||||
const std::string& unit_type::die_sound() const
|
||||
{
|
||||
return cfg_["die_sound"];
|
||||
}
|
||||
|
||||
int unit_type::hitpoints() const
|
||||
{
|
||||
return atoi(cfg_["hitpoints"].c_str());
|
||||
|
@ -132,6 +132,8 @@ public:
|
||||
const std::string& image_fighting(attack_type::RANGE range) const;
|
||||
const std::string& image_defensive(attack_type::RANGE range) const;
|
||||
const std::string& unit_description() const;
|
||||
const std::string& get_hit_sound() const;
|
||||
const std::string& die_sound() const;
|
||||
int hitpoints() const;
|
||||
std::vector<attack_type> attacks() const;
|
||||
const unit_movement_type& movement_type() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user