new lobby: Treat the game id as an int that it is,

...add status icons to player list (icons from patch/bug #11726 by
megane), add server support for differentiating between players
playing and observing a game.
This commit is contained in:
Tomasz Śniatowski 2009-07-20 18:38:28 +01:00
parent a2d950c4b1
commit 4dc9f782b9
20 changed files with 114 additions and 24 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

View file

@ -203,11 +203,20 @@
definition = "default"
[grid]
[row]
[column]
border = "all"
border_size = 1
[image]
id = "main_icon"
definition = "default"
label = ""
[/image]
[/column]
[column]
grow_factor = 1
horizontal_grow = "true"
border = "all"
border_size = 5
border = "top,right,bottom"
border_size = 3
[label]
id = "player"
definition = "default"

View file

@ -194,7 +194,7 @@ tlobby_main::tlobby_main(const config& game_config, lobby_info& info)
, gamelistbox_(NULL), chat_log_container_(NULL)
, chat_input_(NULL), window_(NULL)
, lobby_info_(info), preferences_callback_(NULL)
, open_windows_(), active_window_(0)
, open_windows_(), active_window_(0), selected_game_id_()
{
}
@ -230,6 +230,11 @@ void set_visible_if_exists(tgrid* grid, const char* id, bool visible)
}
}
std::string colorize(const std::string& str, const std::string& color)
{
return "<span color=\"" + color +"\">" + str + "</span>";
}
} //end anonymous namespace
void tlobby_main::update_gamelist()
@ -309,11 +314,50 @@ void tlobby_main::update_gamelist()
}
}
update_selected_game();
lobby_info_.update_user_statuses(selected_game_id_, active_window_room());
userlistbox_->clear();
foreach (const user_info& user, lobby_info_.users())
{
std::map<std::string, string_map> data;
add_label_data(data, "player", user.name);
std::stringstream icon_ss;
std::string name = user.name;
icon_ss << "lobby/status";
switch (user.state) {
case user_info::SEL_ROOM:
/* fall through */
case user_info::LOBBY:
icon_ss << "-lobby";
break;
case user_info::SEL_GAME:
name = colorize(name, "cyan");
icon_ss << (user.observing ? "-obs" : "-playing");
break;
case user_info::GAME:
name = colorize(name, "red");
icon_ss << (user.observing ? "-obs" : "-playing"); break;
default:
ERR_NG << "Bad user state in lobby: " << user.state << "\n";
}
switch (user.relation) {
case user_info::ME:
/* fall through */
case user_info::NEUTRAL:
icon_ss << "-n";
break;
case user_info::FRIEND:
icon_ss << "-f";
break;
case user_info::IGNORED:
icon_ss << "-i";
break;
default:
ERR_NG << "Bad user relation in lobby: " << user.relation << "\n";
}
icon_ss << ".png";
add_label_data(data, "player", name);
add_label_data(data, "main_icon", icon_ss.str());
userlistbox_->add_row(data);
}
window_->invalidate_layout();
@ -327,6 +371,9 @@ void tlobby_main::update_selected_game()
const game_info& game = *lobby_info_.games_filtered()[idx];
can_observe = game.can_observe();
can_join = game.can_join();
selected_game_id_ = game.id;
} else {
selected_game_id_ = 0;
}
window_->get_widget<tbutton>("observe_global", false).set_active(can_observe);
window_->get_widget<tbutton>("join_global", false).set_active(can_join);
@ -392,6 +439,12 @@ void tlobby_main::post_show(twindow& /*window*/)
window_ = NULL;
}
room_info* tlobby_main::active_window_room()
{
const tlobby_chat_window& t = open_windows_[active_window_];
if (t.whisper) return NULL;
return lobby_info_.get_room(t.name);
}
tlobby_chat_window* tlobby_main::room_window_open(const std::string& room, bool open_new)
{
@ -735,7 +788,7 @@ bool tlobby_main::do_game_join(int idx, bool observe)
}
config response;
config& join = response.add_child("join");
join["id"] = game.id;
join["id"] = lexical_cast<std::string>(game.id);
join["observe"] = observe ? "yes" : "no";
if (join && game.password_required) {
std::string password;

View file

@ -115,6 +115,12 @@ private:
*/
legacy_result legacy_result_;
/**
* Get the room* corresponding to the currently active window, or NULL
* if a whisper window is active at the moment
*/
room_info* active_window_room();
/**
* Check if a room window for "room" is open, if open_new is true
* then it will be created if not found.
@ -300,6 +306,8 @@ private:
ttoggle_button* filter_invert_;
ttext_box* filter_text_;
int selected_game_id_;
};
} // namespace gui2

View file

@ -96,15 +96,17 @@ user_info::user_info()
, relation(ME)
, state(LOBBY)
, registered()
, observing()
{
}
user_info::user_info(const config& c)
: name(c["name"])
, game_id(c["game_id"])
, game_id(lexical_cast_default<int>(c["game_id"]))
, relation(ME)
, state(c["available"] == "no" ? GAME : LOBBY)
, state(game_id == 0 ? LOBBY : GAME)
, registered(utils::string_bool(c["registered"]))
, observing(c["status"] == "observing")
{
if (name == preferences::login()) {
relation = ME;
@ -117,12 +119,20 @@ user_info::user_info(const config& c)
}
}
void user_info::update_state(const std::string& selected_game_id, const room_info* current_room /*= NULL*/)
void user_info::update_state(int selected_game_id, const room_info* current_room /*= NULL*/)
{
if (!game_id.empty() && game_id == selected_game_id) {
state = SEL_GAME;
} else if (state == LOBBY && current_room != NULL && current_room->is_member(name)) {
state = SEL_ROOM;
if (game_id != 0) {
if (game_id == selected_game_id) {
state = SEL_GAME;
} else {
state = GAME;
}
} else if (state == LOBBY) {
if (current_room != NULL && current_room->is_member(name)) {
state = SEL_ROOM;
} else {
state = LOBBY;
}
}
}
@ -178,7 +188,7 @@ std::string make_short_name(const std::string long_name)
game_info::game_info(const config& game, const config& game_config)
: mini_map()
, id(game["id"])
, id(lexical_cast_default<int>(game["id"]))
, map_data(game["map_data"])
, name(game["name"])
, scenario()
@ -456,8 +466,8 @@ void lobby_info::parse_gamelist()
games_by_id_.insert(std::make_pair(gi.id, &gi));
}
foreach (user_info& ui, users_) {
if (!ui.game_id.empty()) {
std::map<std::string, game_info*>::iterator i = games_by_id_.find(ui.game_id);
if (ui.game_id != 0) {
std::map<int, game_info*>::iterator i = games_by_id_.find(ui.game_id);
if (i == games_by_id_.end()) {
WRN_NG << "User " << ui.name << " has unknown game_id: " << ui.game_id << "\n";
} else {
@ -551,3 +561,10 @@ void lobby_info::apply_game_filter()
}
}
}
void lobby_info::update_user_statuses(int game_id, const room_info *room)
{
foreach (user_info& user, users_) {
user.update_state(game_id, room);
}
}

View file

@ -88,7 +88,7 @@ struct user_info
user_info();
user_info(const config& c);
void update_state(const std::string& selected_game_id, const room_info* current_room = NULL);
void update_state(int selected_game_id, const room_info* current_room = NULL);
enum user_relation { ME, FRIEND, NEUTRAL, IGNORED };
enum user_state { LOBBY, SEL_ROOM, GAME, SEL_GAME };
@ -96,10 +96,11 @@ struct user_info
bool operator> (const user_info& b) const;
std::string name;
std::string game_id;
int game_id;
user_relation relation;
user_state state;
bool registered;
bool observing;
};
/**
@ -114,7 +115,7 @@ struct game_info
bool can_observe() const;
surface mini_map;
std::string id;
int id;
std::string map_data;
std::string name;
std::string scenario;
@ -269,6 +270,8 @@ public:
chat_log& get_whisper_log(const std::string& name);
void update_user_statuses(int game_id, const room_info* room);
const std::vector<room_info>& rooms() const { return rooms_; }
const std::vector<game_info>& games() const { return games_; }
const std::vector<game_info*>& games_filtered();
@ -281,7 +284,7 @@ private:
bool gamelist_initialized_;
std::vector<room_info> rooms_;
std::vector<game_info> games_;
std::map<std::string, game_info*> games_by_id_;
std::map<int, game_info*> games_by_id_;
std::vector<game_info*> games_filtered_;
std::vector<user_info> users_;
std::map<std::string, chat_log> whispers_;

View file

@ -74,7 +74,7 @@ game::game(player_map& players, const network::connection host,
}
// Mark the host as unavailable in the lobby.
pl->second.mark_available(id_, name_);
p1->second.set_status(player::PLAYING);
pl->second.set_status(player::PLAYING);
}
game::~game()
@ -277,7 +277,7 @@ void game::update_side_data() {
// * Find the username.
// * Find the side this username corresponds to.
for (user_vector::const_iterator user = users.begin(); user != users.end(); ++user) {
const player_map::const_iterator info = player_info_->find(*user);
player_map::iterator info = player_info_->find(*user);
if (info == player_info_->end()) {
ERR_GAME << "Game: " << id_
<< " ERROR: unable to find user info for connection: "
@ -343,7 +343,7 @@ void game::transfer_side_control(const network::connection sock, const simple_wm
const simple_wml::string_span& newplayer_name = cfg["player"];
const network::connection old_player = sides_[side_num - 1];
const player_map::const_iterator oldplayer = player_info_->find(old_player);
const player_map::iterator oldplayer = player_info_->find(old_player);
if (oldplayer == player_info_->end()) {
WRN_GAME << "Could not find old player in player_info_. (socket: "
<< old_player << ")\n";
@ -380,7 +380,7 @@ void game::transfer_side_control(const network::connection sock, const simple_wm
return;
}
//find the player that is passed control
player_map::const_iterator newplayer;
player_map::iterator newplayer;
for (newplayer = player_info_->begin(); newplayer != player_info_->end(); newplayer++) {
if (newplayer_name == newplayer->second.name().c_str()) {
break;
@ -1044,7 +1044,7 @@ bool game::remove_player(const network::connection player, const bool disconnect
if (*side != player) continue;
if (side_controllers_[side_num] == "ai") ai_transfer = true;
player_map::const_iterator o = player_info_->find(owner_);
player_map::iterator o = player_info_->find(owner_);
const std::string owner_name = (o != player_info_->end() ? o->second.name() : "(unknown)");
change_controller(side_num, owner_, owner_name);
// Check whether the host is actually a player and make him one if not.