statistics_dialog::statistics_dialog(game_display &disp, const std::string& title, const unsigned int team, const std::string& team_id, const std::string& player) : dialog(disp.video(), title, "", gui::NULL_DIALOG), detail_btn_(new gui::standard_dialog_button(disp.video(), _("Details"), 0 , false)), toggle_btn_(new gui::dialog_button(disp.video(), "", gui::button::TYPE_PRESS, BUTTON_TOGGLE)), scene_btn_(new gui::dialog_button(disp.video(), _("Select Scenario"), gui::button::TYPE_PRESS, BUTTON_SCENE)), player_name_(player), campaign_(statistics::calculate_stats(team_id)), scenarios_(statistics::level_stats(team_id)), scenario_index_(scenarios_.size() - 1), // current scenario team_num_(team), unit_count_(5,0) { if ( scenarios_.size() > 1 ) { add_button(scene_btn_, gui::dialog::BUTTON_EXTRA_LEFT); add_button(toggle_btn_, gui::dialog::BUTTON_EXTRA_LEFT); } add_button(detail_btn_, gui::dialog::BUTTON_EXTRA); add_button(new gui::standard_dialog_button(disp.video(), _("Close"), 1, true), gui::dialog::BUTTON_STANDARD); // Initialize the displayed data. if ( use_campaign_ || scenarios_.size() == 1 ) display_stats(use_campaign_); else { // Starting with the scenario stats, but we need to make sure the // window is wide enough for the campaign stats. display_stats(true); layout(); display_stats(false); } }
/** * Fade-in the wesnoth-logo. * * Animation-effect: scroll-in from right. \n * Used only once, after the game is started. * * @param screen surface to operate on * @param xpos x-position of logo * @param ypos y-position of logo * * @return Result of running the routine * @retval true operation finished (successful or not) * @retval false operation failed (because modeChanged), need to retry */ static bool fade_logo(game_display& screen, int xpos, int ypos) { const surface logo(image::get_image(game_config::game_logo)); if(logo == NULL) { ERR_DP << "Could not find game logo\n"; return true; } surface const fb = screen.video().getSurface(); if(fb == NULL || xpos < 0 || ypos < 0 || xpos + logo->w > fb->w || ypos + logo->h > fb->h) { return true; } // Only once, when the game is first started, the logo fades in unless // it was disabled in adv. preferences static bool faded_in = !preferences::startup_effect(); // static bool faded_in = true; // for faster startup: mark logo as 'has already faded in' CKey key; bool last_button = key[SDLK_ESCAPE] || key[SDLK_SPACE]; LOG_DP << "fading logo in....\n"; LOG_DP << "logo size: " << logo->w << "," << logo->h << "\n"; for(int x = 0; x != logo->w; ++x) { SDL_Rect srcrect = {x,0,1,logo->h}; SDL_Rect dstrect = {xpos+x,ypos,1,logo->h}; SDL_BlitSurface(logo,&srcrect,fb,&dstrect); update_rect(dstrect); if(!faded_in && (x%5) == 0) { const bool new_button = key[SDLK_ESCAPE] || key[SDLK_SPACE] || key[SDLK_RETURN] || key[SDLK_KP_ENTER] ; if(new_button && !last_button) { faded_in = true; } last_button = new_button; screen.update_display(); screen.delay(10); events::pump(); if(screen.video().modeChanged()) { faded_in = true; return false; } } } LOG_DP << "logo faded in\n"; faded_in = true; return true; }
wait::wait(game_display& disp, const config& cfg, mp::chat& c, config& gamelist) : ui(disp, _("Game Lobby"), cfg, c, gamelist), cancel_button_(disp.video(), _("Cancel")), start_label_(disp.video(), _("Waiting for game to start..."), font::SIZE_SMALL, font::LOBBY_COLOR), game_menu_(disp.video(), std::vector<std::string>(), false, -1, -1, NULL, &gui::menu::bluebg_style), level_(), state_(), stop_updates_(false) { game_menu_.set_numeric_keypress_selection(false); gamelist_updated(); }
static void enter_create_mode(game_display& disp, const config& game_config, hero_map& heros, hero_map& heros_start, card_map& cards, config& gamelist, mp::controller default_controller, bool local_players_only) { mp::ui::result res; mp_game_settings params; int num_turns; // if (gui2::new_widgets) { gui2::tmp_create_game dlg(disp, game_config); dlg.show(disp.video()); int retval = dlg.get_retval(); if (retval == gui2::twindow::OK) { res = mp::ui::CREATE; } else { res = mp::ui::QUIT; } params = dlg.get_parameters(); num_turns = dlg.num_turns(); // network::send_data(config("refresh_lobby"), 0); switch (res) { case mp::ui::CREATE: enter_connect_mode(disp, game_config, heros, heros_start, cards, gamelist, params, num_turns, default_controller, local_players_only); break; case mp::ui::QUIT: default: //update lobby content network::send_data(config("refresh_lobby"), 0); break; } }
static void enter_create_mode(game_display& disp, const config& game_config, mp::chat& chat, config& gamelist, mp::controller default_controller, bool local_players_only) { if (0 && gui2::new_widgets) { gui2::tmp_create_game dlg(game_config); dlg.show(disp.video()); network::send_data(config("refresh_lobby"), 0, true); } else { mp::ui::result res; mp_game_settings params; int num_turns; { mp::create ui(disp, game_config, chat, gamelist); run_lobby_loop(disp, ui); res = ui.get_result(); params = ui.get_parameters(); num_turns = ui.num_turns(); } switch (res) { case mp::ui::CREATE: enter_connect_mode(disp, game_config, chat, gamelist, params, num_turns, default_controller, local_players_only); break; case mp::ui::QUIT: default: //update lobby content network::send_data(config("refresh_lobby"), 0, true); break; } } }
static void enter_wait_mode(game_display& disp, const config& game_config, hero_map& heros, hero_map& heros_start, card_map& cards, config& gamelist, bool observe) { mp::ui::result res; game_state state; network_game_manager m; gamelist.clear(); statistics::fresh_stats(); gui2::tmp_side_wait dlg(heros, disp, *resources::game_map, game_config, gamelist, observe); dlg.show(disp.video()); switch (dlg.get_legacy_result()) { case gui2::tmp_side_wait::PLAY: res = mp::ui::PLAY; dlg.start_game(); state = dlg.get_state(); // lobby may modify hero's side_feature heros_start = heros; break; default: res = mp::ui::QUIT; } switch (res) { case mp::ui::PLAY: play_game(disp, state, game_config, heros, heros_start, cards, IO_CLIENT, preferences::skip_mp_replay() && observe); recorder.clear(); break; case mp::ui::QUIT: default: break; } }
create_engine::create_engine(game_display& disp, saved_game& state) : current_level_type_(), current_level_index_(0), current_era_index_(0), current_mod_index_(0), level_name_filter_(), player_count_filter_(1), scenarios_(), user_maps_(), user_scenarios_(), campaigns_(), sp_campaigns_(), random_maps_(), user_map_names_(), user_scenario_names_(), eras_(), mods_(), state_(state), dependency_manager_(resources::config_manager->game_config(), disp.video()), generator_(NULL) { DBG_MP << "restoring game config\n"; // Restore game config for multiplayer. state_ = saved_game(); state_.classification().campaign_type = game_classification::MULTIPLAYER; resources::config_manager-> load_game_config_for_game(state_.classification()); //TODO the editor dir is already configurable, is the preferences value get_files_in_dir(get_user_data_dir() + "/editor/maps", &user_map_names_, NULL, FILE_NAME_ONLY); get_files_in_dir(get_user_data_dir() + "/editor/scenarios", &user_scenario_names_, NULL, FILE_NAME_ONLY); DBG_MP << "initializing all levels, eras and mods\n"; init_all_levels(); init_extras(ERA); init_extras(MOD); state_.mp_settings().saved_game = false; BOOST_FOREACH (const std::string& str, preferences::modifications()) { if (resources::config_manager-> game_config().find_child("modification", "id", str)) state_.mp_settings().active_mods.push_back(str); } if (current_level_type_ != level::CAMPAIGN && current_level_type_ != level::SP_CAMPAIGN) { dependency_manager_.try_modifications(state_.mp_settings().active_mods, true); } reset_level_filters(); }
void floating_textbox::show(gui::TEXTBOX_MODE mode, const std::string& label, const std::string& check_label, bool checked, game_display& gui) { close(gui); label_string_ = label; mode_ = mode; if(check_label != "") { check_.assign(new gui::button(gui.video(),check_label,gui::button::TYPE_CHECK)); check_->set_check(checked); } box_.assign(new gui::textbox(gui.video(),100,"",true,256,0.8,0.6)); update_location(gui); }
wait::wait(game_display& disp, const config& cfg, saved_game& state, mp::chat& c, config& gamelist, const bool first_scenario) : ui(disp, _("Game Lobby"), cfg, c, gamelist), cancel_button_(disp.video(), first_scenario ? _("Cancel") : _("Quit")), start_label_(disp.video(), _("Waiting for game to start..."), font::SIZE_SMALL, font::LOBBY_COLOR), game_menu_(disp.video(), std::vector<std::string>(), false, -1, -1, NULL, &gui::menu::bluebg_style), level_(), state_(state), first_scenario_(first_scenario), stop_updates_(false) { game_menu_.set_numeric_keypress_selection(false); gamelist_updated(); plugins_context_.reset(new plugins_context("Multiplayer Wait")); //These structure initializers create a lobby::process_data_event plugins_context_->set_callback("quit", boost::bind(&wait::process_event_impl, this, true), false); plugins_context_->set_callback("chat", boost::bind(&wait::send_chat_message, this, boost::bind(get_str, _1, "message"), false), true); }
static void enter_create_mode(game_display& disp, const config& game_config, game_state& state, bool local_players_only) { DBG_MP << "entering create mode" << std::endl; bool configure_canceled; bool connect_canceled; do { configure_canceled = false; connect_canceled = false; if (gui2::new_widgets) { gui2::tmp_create_game dlg(game_config); dlg.show(disp.video()); network::send_data(config("refresh_lobby"), 0); } else { mp::ui::result res; mp_game_settings new_params; { mp::create ui(disp, game_config, state, gamechat, gamelist); run_lobby_loop(disp, ui); res = ui.get_result(); new_params = ui.get_parameters(); } switch (res) { case mp::ui::CREATE: configure_canceled = !enter_configure_mode(disp, game_config, state, new_params, local_players_only); break; case mp::ui::LOAD_GAME: connect_canceled = !enter_connect_mode(disp, game_config, state, new_params, local_players_only); break; case mp::ui::QUIT: default: //update lobby content network::send_data(config("refresh_lobby"), 0); break; } } } while(configure_canceled || connect_canceled); }
static void enter_connect_mode(game_display& disp, const config& game_config, hero_map& heros, hero_map& heros_start, card_map& cards, config& gamelist, const mp_game_settings& params, const int num_turns, mp::controller default_controller, bool local_players_only = false) { mp::ui::result res; game_state state; const network::manager net_manager(1,1); network_game_manager m; gamelist.clear(); statistics::fresh_stats(); // if (gui2::new_widgets) { gui2::tmp_side_creator dlg(heros, disp, *resources::game_map, game_config, gamelist, params, num_turns, default_controller, local_players_only); dlg.show(disp.video()); switch (dlg.get_legacy_result()) { case gui2::tmp_side_creator::PLAY: res = mp::ui::PLAY; dlg.start_game(); state = dlg.get_state(); // lobby may modify hero's side_feature heros_start = heros; break; case gui2::tmp_side_creator::CREATE: res = mp::ui::CREATE; break; default: res = mp::ui::QUIT; } switch (res) { case mp::ui::PLAY: play_game(disp, state, game_config, heros, heros_start, cards, IO_SERVER); recorder.clear(); break; case mp::ui::CREATE: enter_create_mode(disp, game_config, heros, heros_start, cards, gamelist, default_controller, local_players_only); break; case mp::ui::QUIT: default: network::send_data(config("refresh_lobby"), 0); break; } }
static void do_preferences_dialog(game_display& disp, const config& game_config) { const preferences::display_manager disp_manager(&disp); preferences::show_preferences_dialog(disp,game_config); /** * The screen size might have changed force an update of the size. * * @todo This might no longer be needed when gui2 is done. */ const SDL_Rect rect = screen_area(); preferences::set_resolution(disp.video(), rect.w, rect.h); gui2::settings::gamemap_width += rect.w - gui2::settings::screen_width ; gui2::settings::gamemap_height += rect.h - gui2::settings::screen_height ; gui2::settings::screen_width = rect.w; gui2::settings::screen_height = rect.h; }
create::create(game_display& disp, const config& cfg, saved_game& state, chat& c, config& gamelist) : ui(disp, _("Create Game"), cfg, c, gamelist), tooltip_manager_(disp.video()), era_selection_(-1), mod_selection_(-1), level_selection_(-1), eras_menu_(disp.video(), std::vector<std::string>()), levels_menu_(disp.video(), std::vector<std::string>()), mods_menu_(disp.video(), std::vector<std::string>()), filter_name_label_(disp.video(), _("Filter:"), font::SIZE_SMALL, font::LOBBY_COLOR), filter_num_players_label_(disp.video(), _("Number of players: any"), font::SIZE_SMALL, font::LOBBY_COLOR), map_generator_label_(disp.video(), _("Random map options:"), font::SIZE_SMALL, font::LOBBY_COLOR), era_label_(disp.video(), _("Era:"), font::SIZE_SMALL, font::LOBBY_COLOR), no_era_label_(disp.video(), _("No eras available\nfor this game."), font::SIZE_SMALL, font::LOBBY_COLOR), mod_label_(disp.video(), _("Modifications:"), font::SIZE_SMALL, font::LOBBY_COLOR), map_size_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR), num_players_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR), level_type_label_(disp.video(), "Game type:", font::SIZE_SMALL, font::LOBBY_COLOR), launch_game_(disp.video(), _("Next")), cancel_game_(disp.video(), _("Cancel")), regenerate_map_(disp.video(), _("Regenerate")), generator_settings_(disp.video(), _("Settings...")), load_game_(disp.video(), _("Load Game...")), level_type_combo_(disp, std::vector<std::string>()), filter_num_players_slider_(disp.video()), description_(disp.video(), 100, "", false), filter_name_(disp.video(), 100, "", true, 256, font::SIZE_SMALL), image_restorer_(NULL), image_rect_(null_rect), available_level_types_(), engine_(disp, state) { filter_num_players_slider_.set_min(1); filter_num_players_slider_.set_max(9); filter_num_players_slider_.set_increment(1); DBG_MP << "constructing multiplayer create dialog" << std::endl; levels_menu_.set_numeric_keypress_selection(false); typedef std::pair<ng::level::TYPE, std::string> level_type_info; std::vector<level_type_info> all_level_types; all_level_types.push_back(std::make_pair(ng::level::TYPE::SCENARIO, _("Scenarios"))); all_level_types.push_back(std::make_pair(ng::level::TYPE::CAMPAIGN, _("Campaigns"))); all_level_types.push_back(std::make_pair(ng::level::TYPE::USER_MAP, _("User Maps"))); all_level_types.push_back(std::make_pair(ng::level::TYPE::USER_SCENARIO, _("User Scenarios"))); all_level_types.push_back(std::make_pair(ng::level::TYPE::RANDOM_MAP, _("Random Maps"))); if (game_config::debug) { all_level_types.push_back(std::make_pair(ng::level::TYPE::SP_CAMPAIGN, "SP Campaigns")); } std::vector<std::string> combo_level_names; BOOST_FOREACH(level_type_info type_info, all_level_types) { if (!engine_.get_levels_by_type_unfiltered(type_info.first).empty()) { available_level_types_.push_back(type_info.first); combo_level_names.push_back(type_info.second); } } if (available_level_types_.empty()) { gui2::show_transient_message(disp.video(), "", _("No games found.")); throw game::error(_("No games found.")); } level_type_combo_.set_items(combo_level_names); size_t combo_new_selection = 0; size_t level_new_selection = 0; // Set level selection according to the preferences, if possible. size_t type_index = 0; BOOST_FOREACH(ng::level::TYPE type, available_level_types_) { if (preferences::level_type() == type.cast<int>()) { break; } type_index++; } if (type_index < available_level_types_.size()) { combo_new_selection = type_index; int level_index = engine_.find_level_by_id(preferences::level()); if (level_index != -1) { level_new_selection = level_index; } } level_type_combo_.set_selected(combo_new_selection); init_level_type_changed(level_new_selection); const std::vector<std::string>& era_names = engine_.extras_menu_item_names(ng::create_engine::ERA); if(era_names.empty()) { gui2::show_transient_message(disp.video(), "", _("No eras found.")); throw config::error(_("No eras found")); } eras_menu_.set_items(era_names); // Set era selection according to the preferences, if possible. int era_new_selection = engine_.find_extra_by_id(ng::create_engine::ERA, preferences::era()); eras_menu_.move_selection((era_new_selection != -1) ? era_new_selection : 0); std::vector<std::string> mods = engine_.extras_menu_item_names(ng::create_engine::MOD); mods_menu_.set_items(mods); mods_menu_.move_selection(0); // don't set 0 explicitly, because move_selection(0) may fail if there's // no modifications at all mod_selection_ = mods_menu_.selection(); if (mod_selection_ == -1) { mod_label_.set_text(_("Modifications:\nNone found.")); } gamelist_updated(); plugins_context_.reset(new plugins_context("Multiplayer Create")); //These structure initializers create a lobby::process_data_event plugins_context_->set_callback("create", boost::bind(&create::plugin_event_helper, this, process_event_data (true, false, false))); plugins_context_->set_callback("load", boost::bind(&create::plugin_event_helper, this, process_event_data (false, true, false))); plugins_context_->set_callback("quit", boost::bind(&create::plugin_event_helper, this, process_event_data (false, false, true))); plugins_context_->set_callback("chat", boost::bind(&create::send_chat_message, this, boost::bind(get_str, _1, "message"), false), true); plugins_context_->set_callback("select_level", boost::bind(&gui::menu::move_selection, &levels_menu_, boost::bind(get_size_t, _1, "index", 0u)), true); plugins_context_->set_callback("select_type", boost::bind(&create::select_level_type_helper, this, boost::bind(get_str, _1, "type")), true); plugins_context_->set_accessor("game_config", boost::bind(&create::game_config, this)); plugins_context_->set_accessor("get_selected", boost::bind(&get_selected_helper, &engine_)); plugins_context_->set_accessor("find_level", boost::bind(&find_helper, &engine_, _1)); }
static void enter_lobby_mode(game_display& disp, const config& game_config, mp::chat& chat, config& gamelist) { mp::ui::result res; while (true) { const config &cfg = game_config.child("lobby_music"); if (cfg) { foreach (const config &i, cfg.child_range("music")) { sound::play_music_config(i); } sound::commit_music_changes(); } else { sound::empty_playlist(); sound::stop_music(); } lobby_info li(game_config); gui2::tlobby_main dlg(game_config, li, disp); dlg.set_preferences_callback( boost::bind(do_preferences_dialog, boost::ref(disp), boost::ref(game_config))); dlg.show(disp.video()); //ugly kludge for launching other dialogs like the old lobby switch (dlg.get_legacy_result()) { case gui2::tlobby_main::CREATE: res = mp::ui::CREATE; break; case gui2::tlobby_main::JOIN: res = mp::ui::JOIN; break; case gui2::tlobby_main::OBSERVE: res = mp::ui::OBSERVE; break; default: res = mp::ui::QUIT; } switch (res) { case mp::ui::JOIN: try { enter_wait_mode(disp, game_config, chat, gamelist, false); } catch(config::error& error) { if(!error.message.empty()) { gui2::show_error_message(disp.video(), error.message); } //update lobby content network::send_data(config("refresh_lobby"), 0, true); } break; case mp::ui::OBSERVE: try { enter_wait_mode(disp, game_config, chat, gamelist, true); } catch(config::error& error) { if(!error.message.empty()) { gui2::show_error_message(disp.video(), error.message); } } // update lobby content unconditionally because we might have left only after the // game ended in which case we ignored the gamelist and need to request it again network::send_data(config("refresh_lobby"), 0, true); break; case mp::ui::CREATE: try { enter_create_mode(disp, game_config, chat, gamelist, mp::CNTR_NETWORK); } catch(config::error& error) { if (!error.message.empty()) gui2::show_error_message(disp.video(), error.message); //update lobby content network::send_data(config("refresh_lobby"), 0, true); } break; case mp::ui::QUIT: return; case mp::ui::PREFERENCES: { do_preferences_dialog(disp, game_config); //update lobby content network::send_data(config("refresh_lobby"), 0, true); } break; default: return; } }
statistics_dialog::statistics_dialog(game_display &disp, const std::string& title, const unsigned int team, const std::string& team_id, const std::string& player) : dialog(disp, title, "", gui::NULL_DIALOG), detail_btn_(new gui::standard_dialog_button(disp.video(), _("Details"), 0 , false)), player_name_(player), stats_(), team_num_(team), unit_count_(5,0) { add_button(detail_btn_, gui::dialog::BUTTON_EXTRA); add_button(new gui::standard_dialog_button(disp.video(), _("Close"), 1, true), gui::dialog::BUTTON_STANDARD); stats_ = statistics::calculate_stats(0, team_id); int n, cost; std::vector<std::string> items; // Prepare the menu items { std::stringstream str; n = statistics::sum_str_int_map(stats_.recruits); cost = stats_.recruit_cost; unit_count_[0] = n; str << _("Recruits") << COLUMN_SEPARATOR << n << COLUMN_SEPARATOR << COLUMN_SEPARATOR << IMAGE_PREFIX << "themes/gold-t.png" << COLUMN_SEPARATOR << cost; items.push_back(str.str()); } { std::stringstream str; n = statistics::sum_str_int_map(stats_.recalls); cost = stats_.recall_cost; unit_count_[1] = n; str << _("Recalls") << COLUMN_SEPARATOR << n << COLUMN_SEPARATOR << COLUMN_SEPARATOR << IMAGE_PREFIX << "themes/gold-t.png" << COLUMN_SEPARATOR << cost; items.push_back(str.str()); } { std::stringstream str; n = statistics::sum_str_int_map(stats_.advanced_to); unit_count_[2] = n; str << _("Advancements") << COLUMN_SEPARATOR << n; items.push_back(str.str()); } { std::stringstream str; n = statistics::sum_str_int_map(stats_.deaths); unit_count_[3] = n; cost = statistics::sum_cost_str_int_map(stats_.deaths); str << _("Losses") << COLUMN_SEPARATOR << n << COLUMN_SEPARATOR << COLUMN_SEPARATOR << IMAGE_PREFIX << "themes/gold-t.png" << COLUMN_SEPARATOR << cost; items.push_back(str.str()); } { std::stringstream str; n = statistics::sum_str_int_map(stats_.killed); unit_count_[4] = n; cost = statistics::sum_cost_str_int_map(stats_.killed); str << _("Kills") << COLUMN_SEPARATOR << n << COLUMN_SEPARATOR << COLUMN_SEPARATOR << IMAGE_PREFIX << "themes/gold-t.png" << COLUMN_SEPARATOR << cost; items.push_back(str.str()); } items.push_back(""); { std::stringstream str; str << font::BOLD_TEXT << _("Damage") << COLUMN_SEPARATOR << _("Overall") << COLUMN_SEPARATOR << COLUMN_SEPARATOR << COLUMN_SEPARATOR << _("This Turn"); items.push_back(str.str()); } statistics_dialog::make_damage_line(items, _("Inflicted"), stats_.damage_inflicted, stats_.expected_damage_inflicted, stats_.turn_damage_inflicted, stats_.turn_expected_damage_inflicted); statistics_dialog::make_damage_line(items, _("Taken"), stats_.damage_taken, stats_.expected_damage_taken, stats_.turn_damage_taken, stats_.turn_expected_damage_taken); set_menu(items); }
static server_type open_connection(game_display& disp, const std::string& original_host) { std::string h = original_host; if(h.empty()) { gui2::tmp_connect dlg; dlg.show(disp.video()); if(dlg.get_retval() == gui2::twindow::OK) { h = preferences::network_host(); } else { return ABORT_SERVER; } } network::connection sock; const int pos = h.find_first_of(":"); std::string host; unsigned int port; if(pos == -1) { host = h; port = 15000; } else { host = h.substr(0, pos); port = lexical_cast_default<unsigned int>(h.substr(pos + 1), 15000); } // shown_hosts is used to prevent the client being locked in a redirect // loop. typedef std::pair<std::string, int> hostpair; std::set<hostpair> shown_hosts; shown_hosts.insert(hostpair(host, port)); config data; sock = dialogs::network_connect_dialog(disp,_("Connecting to Server..."),host,port); do { if (!sock) { return ABORT_SERVER; } data.clear(); network::connection data_res = dialogs::network_receive_dialog( disp,_("Reading from Server..."),data); if (!data_res) return ABORT_SERVER; mp::check_response(data_res, data); // Backwards-compatibility "version" attribute const std::string& version = data["version"]; if(version.empty() == false && version != game_config::version) { utils::string_map i18n_symbols; i18n_symbols["version1"] = version; i18n_symbols["version2"] = game_config::version; const std::string errorstring = vgettext("The server requires version '$version1' while you are using version '$version2'", i18n_symbols); throw network::error(errorstring); } // Check for "redirect" messages if (const config &redirect = data.child("redirect")) { host = redirect["host"]; port = lexical_cast_default<unsigned int>(redirect["port"], 15000); if(shown_hosts.find(hostpair(host,port)) != shown_hosts.end()) { throw network::error(_("Server-side redirect loop")); } shown_hosts.insert(hostpair(host, port)); if(network::nconnections() > 0) network::disconnect(); sock = dialogs::network_connect_dialog(disp,_("Connecting to Server..."),host,port); continue; } if(data.child("version")) { config cfg; config res; cfg["version"] = game_config::version; res.add_child("version", cfg); network::send_data(res, 0, true); } //if we got a direction to login if(data.child("mustlogin")) { for(;;) { std::string password_reminder = ""; std::string login = preferences::login(); config response ; config &sp = response.add_child("login") ; sp["username"] = login ; // Login and enable selective pings -- saves server bandwidth // If ping_timeout has a non-zero value, do not enable // selective pings as this will cause clients to falsely // believe the server has died and disconnect. if( preferences::get_ping_timeout() ) { // Pings required so disable selective pings sp["selective_ping"] = "0" ; } else { // Client is bandwidth friendly so allow // server to optimize ping frequency as needed. sp["selective_ping"] = "1" ; } network::send_data(response, 0, true); // Get response for our login request... network::connection data_res = network::receive_data(data, 0, 3000); if(!data_res) { throw network::error(_("Connection timed out")); } config *error = &data.child("error"); // ... and get us out of here if the server did not complain if (!*error) break; do { std::string password = preferences::password(); bool fall_through = (*error)["force_confirmation"] == "yes" ? (gui::dialog(disp,_("Confirm"),(*error)["message"],gui::OK_CANCEL).show() != 0) : false; const bool is_pw_request = !((*error)["password_request"].empty()) && !(password.empty()); // If the server asks for a password, provide one if we can // or request a password reminder. // Otherwise or if the user pressed 'cancel' in the confirmation dialog // above go directly to the username/password dialog if((is_pw_request || !password_reminder.empty()) && !fall_through) { if(is_pw_request) { if((*error)["phpbb_encryption"] == "yes") { // Apparently HTML key-characters are passed to the hashing functions of phpbb in this escaped form. // I will do closer investigations on this, for now let's just hope these are all of them. // Note: we must obviously replace '&' first, I wasted some time before I figured that out... :) for(std::string::size_type pos = 0; (pos = password.find('&', pos)) != std::string::npos; ++pos ) password.replace(pos, 1, "&"); for(std::string::size_type pos = 0; (pos = password.find('\"', pos)) != std::string::npos; ++pos ) password.replace(pos, 1, """); for(std::string::size_type pos = 0; (pos = password.find('<', pos)) != std::string::npos; ++pos ) password.replace(pos, 1, "<"); for(std::string::size_type pos = 0; (pos = password.find('>', pos)) != std::string::npos; ++pos ) password.replace(pos, 1, ">"); const std::string salt = (*error)["salt"]; if (salt.length() < 12) { //TODO gettextify after end of stringfreeze throw network::error("Bad data received from server"); } sp["password"] = util::create_hash(util::create_hash(password, util::get_salt(salt), util::get_iteration_count(salt)), salt.substr(12, 8)); } else { sp["password"] = password; } } sp["password_reminder"] = password_reminder; // Once again send our request... network::send_data(response, 0, true); network::connection data_res = network::receive_data(data, 0, 3000); if(!data_res) { throw network::error(_("Connection timed out")); } error = &data.child("error"); // ... and get us out of here if the server is happy now if (!*error) break; } password_reminder = ""; // Providing a password either was not attempted because we did not // have any or failed: // Now show a dialog that displays the error and allows to // enter a new user name and/or password std::string error_message; utils::string_map i18n_symbols; i18n_symbols["nick"] = login; if((*error)["error_code"] == MP_MUST_LOGIN) { error_message = _("You must login first."); } else if((*error)["error_code"] == MP_NAME_TAKEN_ERROR) { error_message = vgettext("The nick '$nick' is already taken.", i18n_symbols); } else if((*error)["error_code"] == MP_INVALID_CHARS_IN_NAME_ERROR) { error_message = vgettext("The nick '$nick' contains invalid " "characters. Only alpha-numeric characters, underscores and " "hyphens are allowed.", i18n_symbols); } else if((*error)["error_code"] == MP_NAME_TOO_LONG_ERROR) { error_message = vgettext("The nick '$nick' is too long. Nicks must " "be 18 characters or less.", i18n_symbols); } else if((*error)["error_code"] == MP_NAME_RESERVED_ERROR) { error_message = vgettext("The nick '$nick' is reserved and cannot be used by players.", i18n_symbols); } else if((*error)["error_code"] == MP_NAME_UNREGISTERED_ERROR) { error_message = vgettext("The nick '$nick' is not registered on this server.", i18n_symbols) + _(" This server disallows unregistered nicks."); } else if((*error)["error_code"] == MP_PASSWORD_REQUEST) { error_message = vgettext("The nick '$nick' is registered on this server.", i18n_symbols); } else if((*error)["error_code"] == MP_PASSWORD_REQUEST_FOR_LOGGED_IN_NAME) { error_message = vgettext("The nick '$nick' is registered on this server.", i18n_symbols) + "\n\n" + _("WARNING: There is already a client using this nick, " "logging in will cause that client to be kicked!"); } else if((*error)["error_code"] == MP_NO_SEED_ERROR) { error_message = _("Error in the login procedure (the server had no " "seed for your connection)."); } else if((*error)["error_code"] == MP_INCORRECT_PASSWORD_ERROR) { error_message = _("The password you provided was incorrect."); } else { error_message = (*error)["message"]; } gui2::tmp_login dlg(error_message, !((*error)["password_request"].empty())); dlg.show(disp.video()); switch(dlg.get_retval()) { //Log in with password case gui2::twindow::OK: break; //Request a password reminder case 1: password_reminder = "yes"; break; // Cancel default: return ABORT_SERVER; } // If we have got a new username we have to start all over again } while(login == preferences::login()); // Somewhat hacky... // If we broke out of the do-while loop above error // is still going to be NULL if(!*error) break; } // end login loop } } while(!(data.child("join_lobby") || data.child("join_game"))); if (h != preferences::server_list().front().address) preferences::set_network_host(h); if (data.child("join_lobby")) { return WESNOTHD_SERVER; } else { return SIMPLE_SERVER; } }
bool enter_create_mode(game_display& disp, const config& game_config, saved_game& state, jump_to_campaign_info jump_to_campaign, bool local_players_only) { bool configure_canceled = false; do { ng::create_engine create_eng(disp, state); create_eng.set_current_level_type(ng::level::TYPE::SP_CAMPAIGN); std::vector<ng::create_engine::level_ptr> campaigns( create_eng.get_levels_by_type_unfiltered(ng::level::TYPE::SP_CAMPAIGN)); if (campaigns.empty()) { gui2::show_error_message(disp.video(), _("No campaigns are available.\n")); return false; } bool use_deterministic_mode = false; // No campaign selected from command line if (jump_to_campaign.campaign_id_.empty() == true) { gui2::tcampaign_selection dlg(create_eng); try { dlg.show(disp.video()); } catch(twml_exception& e) { e.show(disp); return false; } if(dlg.get_retval() != gui2::twindow::OK) { return false; } use_deterministic_mode = dlg.get_deterministic(); } else { // don't reset the campaign_id_ so we can know // if we should quit the game or return to the main menu // checking for valid campaign name bool not_found = true; for(size_t i = 0; i < campaigns.size(); ++i) { if (campaigns[i]->data()["id"] == jump_to_campaign.campaign_id_) { create_eng.set_current_level(i); not_found = false; break; } } // didn't find any campaign with that id if (not_found) { //TODO: use ERR_NG or similar std::cerr<<"No such campaign id to jump to: ["<<jump_to_campaign.campaign_id_<<"]\n"; return false; } } std::string random_mode = use_deterministic_mode ? "deterministic" : ""; state.classification().random_mode = random_mode; std::string selected_difficulty = create_eng.select_campaign_difficulty(jump_to_campaign.difficulty_); if (selected_difficulty == "FAIL") return false; if (selected_difficulty == "CANCEL") { if (jump_to_campaign.campaign_id_.empty() == false) { jump_to_campaign.campaign_id_ = ""; } // canceled difficulty dialog, relaunch the campaign selection dialog return enter_create_mode(disp, game_config, state, jump_to_campaign, local_players_only); } create_eng.prepare_for_era_and_mods(); create_eng.prepare_for_campaign(selected_difficulty); if(!jump_to_campaign.scenario_id_.empty()) { state.set_carryover_sides_start( config_of("next_scenario", jump_to_campaign.scenario_id_) ); } create_eng.prepare_for_new_level(); create_eng.get_parameters(); if(!state.valid()) { //TODO: use ERR_NG or similar std::cerr << "Cannot load scenario with id=" << state.get_scenario_id() << "\n"; return false; } configure_canceled = !enter_configure_mode(disp, game_config_manager::get()->game_config(), state, local_players_only); } while (configure_canceled); return true; }
static void enter_lobby_mode(game_display& disp, const config& game_config, game_state& state) { DBG_MP << "entering lobby mode" << std::endl; mp::ui::result res; while (true) { const config &cfg = game_config.child("lobby_music"); if (cfg) { BOOST_FOREACH(const config &i, cfg.child_range("music")) { sound::play_music_config(i); } sound::commit_music_changes(); } else { sound::empty_playlist(); sound::stop_music(); } lobby_info li(game_config); // Force a black background const Uint32 color = SDL_MapRGBA(disp.video().getSurface()->format , 0 , 0 , 0 , 255); sdl_fill_rect(disp.video().getSurface(), NULL, color); if(preferences::new_lobby()) { gui2::tlobby_main dlg(game_config, li, disp); dlg.set_preferences_callback( boost::bind(do_preferences_dialog, boost::ref(disp), boost::ref(game_config))); dlg.show(disp.video()); //ugly kludge for launching other dialogs like the old lobby switch (dlg.get_legacy_result()) { case gui2::tlobby_main::CREATE: res = mp::ui::CREATE; break; case gui2::tlobby_main::JOIN: res = mp::ui::JOIN; break; case gui2::tlobby_main::OBSERVE: res = mp::ui::OBSERVE; break; default: res = mp::ui::QUIT; } } else { mp::lobby ui(disp, game_config, gamechat, gamelist); run_lobby_loop(disp, ui); res = ui.get_result(); } switch (res) { case mp::ui::JOIN: try { enter_wait_mode(disp, game_config, state, false); } catch(config::error& error) { if(!error.message.empty()) { gui2::show_error_message(disp.video(), error.message); } //update lobby content network::send_data(config("refresh_lobby"), 0); } break; case mp::ui::OBSERVE: try { enter_wait_mode(disp, game_config, state, true); } catch(config::error& error) { if(!error.message.empty()) { gui2::show_error_message(disp.video(), error.message); } } // update lobby content unconditionally because we might have left only after the // game ended in which case we ignored the gamelist and need to request it again network::send_data(config("refresh_lobby"), 0); break; case mp::ui::CREATE: try { enter_create_mode(disp, game_config, state, false); } catch(config::error& error) { if (!error.message.empty()) gui2::show_error_message(disp.video(), error.message); //update lobby content network::send_data(config("refresh_lobby"), 0); } break; case mp::ui::QUIT: return; case mp::ui::PREFERENCES: { do_preferences_dialog(disp, game_config); //update lobby content network::send_data(config("refresh_lobby"), 0); } break; default: return; } }
TITLE_RESULT show_title(game_display& screen, config& tips_of_day) { disableTerrainCache(); free_all_caches(); cursor::set(cursor::NORMAL); const preferences::display_manager disp_manager(&screen); const hotkey::basic_handler key_handler(&screen); const font::floating_label_context label_manager; screen.video().modeChanged(); // resets modeChanged value // if (background_is_dirty_) { draw_background(screen); } //- Texts for the menu-buttons. //- Members of this array must correspond to the enumeration TITLE_RESULT static const char* button_labels[] = { //N_("TitleScreen button^Tutorial"), N_("TitleScreen button^Campaign"), #ifndef FREE_VERSION N_("TitleScreen button^Skirmish"), N_("TitleScreen button^Multiplayer"), #endif N_("TitleScreen button^Load"), // N_("TitleScreen button^Add-ons"), //#ifndef DISABLE_EDITOR2 //N_("TitleScreen button^Map Editor"), //#endif //N_("TitleScreen button^Language"), N_("TitleScreen button^Preferences"), N_("Sync Saves"), #ifndef DISABLE_OPENFEINT N_("TitleScreen button^OpenFeint"), #endif N_("TitleScreen button^Help"), //N_("TitleScreen button^Quit"), // Only the above buttons go into the menu-frame // Next 2 buttons go into frame for the tip-of-the-day: N_("TitleScreen button^Previous"), N_("TitleScreen button^Next"), //N_("TitleScreen button^Help"), // Next entry is no button, but shown as a mail-icon instead: //N_("TitleScreen button^Help Wesnoth") }; //- Texts for the tooltips of the menu-buttons static const char* help_button_labels[] = { //N_("Start a tutorial to familiarize yourself with the game"), N_("Start a new single player campaign"), #ifndef FREE_VERSION N_("Play a single scenario against the AI"), N_("Play multiplayer (hotseat or Internet)"), #endif N_("Load a saved game"), // N_("Download usermade campaigns, eras, or map packs"), //#ifndef DISABLE_EDITOR2 //N_("Start the map editor"), //#endif //N_("Change the language"), N_("Configure the game's settings"), N_("Sync saved games"), #ifndef DISABLE_OPENFEINT N_("Launch the OpenFeint dashboard"), #endif N_("Show Battle for Wesnoth help"), //N_("Quit the game"), N_("Show next tip of the day"), //N_("Upload statistics") }; //static const size_t nbuttons = sizeof(button_labels)/sizeof(*button_labels); #ifdef FREE_VERSION int nbuttons = 10; #else int nbuttons = 8; #endif #ifdef DISABLE_OPENFEINT nbuttons--; #endif #ifndef __IPAD__ nbuttons--; // because help is off to the left now #endif int menu_xbase = CVideo::getx()-108-10; //380; //(game_config::title_buttons_x*screen.w())/1024; const int menu_xincr = 0; #ifdef USE_TINY_GUI //const int menu_ybase = 15; //(330*screen.h())/768 - 50; //15; const int menu_yincr = 36+5; //(35*3)/4;//15; const int menu_ybase = (screen.h() - (36+5)*nbuttons - 5) / 2 + 4; #else const int menu_ybase = (screen.h() - (36+5)*nbuttons - 5) / 2 + 4; const int menu_yincr = 36+5; #endif #ifdef __IPAD__ menu_xbase -= 10; #endif const int padding = 4; //game_config::title_buttons_padding; std::vector<button> buttons; size_t b, max_width = 0; size_t n_menubuttons = 0; for(b = 0; b != nbuttons; ++b) { //#ifdef __IPHONEOS__ // if (b + TUTORIAL == TUTORIAL || b + TUTORIAL == START_MAP_EDITOR || b+TUTORIAL == CHANGE_LANGUAGE) // continue; //#endif buttons.push_back(button(screen.video(),sgettext(button_labels[b]))); buttons.back().set_help_string(sgettext(help_button_labels[b])); max_width = std::max<size_t>(max_width,buttons.back().width()); n_menubuttons = b; #ifdef __IPAD__ if(b + NEW_CAMPAIGN == SHOW_HELP) break; #else if(b + NEW_CAMPAIGN == SHOW_OPENFEINT) break; #endif } SDL_Rect main_dialog_area = {menu_xbase-padding, menu_ybase-padding, max_width+padding*2, menu_yincr*(n_menubuttons)+buttons.back().height()+padding*2}; gui::dialog_frame main_frame(screen.video(), "", gui::dialog_frame::titlescreen_style, false); main_frame.layout(main_dialog_area); // we only redraw transparent parts when asked, // to prevent alpha growing if (background_is_dirty_) { main_frame.draw_background(); main_frame.draw_border(); } int i=0; for(b = 0; b != nbuttons; ++b) { //#ifdef __IPHONEOS__ // if (b + TUTORIAL == TUTORIAL || b + TUTORIAL == START_MAP_EDITOR || b+TUTORIAL == CHANGE_LANGUAGE) // continue; //#endif buttons[i].set_width(max_width); buttons[i].set_location(menu_xbase + i*menu_xincr, menu_ybase + i*menu_yincr); #ifdef __IPAD__ if(b + NEW_CAMPAIGN == SHOW_HELP) break; #else if(b + NEW_CAMPAIGN == SHOW_OPENFEINT) break; #endif i++; } #ifndef __IPAD__ buttons.push_back(button(screen.video(),sgettext(button_labels[i+1]))); buttons.back().set_help_string(sgettext(help_button_labels[i+1])); buttons[i+1].set_width(max_width); buttons[i+1].set_location(5, 320-menu_yincr); #endif // b = TIP_PREVIOUS - NEW_CAMPAIGN; // gui::button previous_tip_button(screen.video(),sgettext(button_labels[b]),button::TYPE_PRESS,"lite_small"); // previous_tip_button.set_help_string( sgettext(button_labels[b] )); // b = TIP_NEXT - NEW_CAMPAIGN; // gui::button next_tip_button(screen.video(),sgettext(button_labels[b]),button::TYPE_PRESS,"lite_small"); // next_tip_button.set_help_string( sgettext(button_labels[b] )); // b = SHOW_HELP - NEW_CAMPAIGN; // gui::button help_tip_button(screen.video(),sgettext(button_labels[b]),button::TYPE_PRESS,"lite_small"); // help_tip_button.set_help_string( sgettext(button_labels[b] )); // gui::button beg_button(screen.video(),_("Help Wesnoth"),button::TYPE_IMAGE,"menu-button",button::MINIMUM_SPACE); // beg_button.set_help_string(_("Help Wesnoth by sending us information")); // next_tip_of_day(tips_of_day); // surface_restorer tip_of_day_restorer; // draw_tip_of_day(screen, tips_of_day, gui::dialog_frame::titlescreen_style, // &previous_tip_button, &next_tip_button, NULL/*&help_tip_button*/, &main_dialog_area, tip_of_day_restorer); // const int pad = game_config::title_tip_padding; // beg_button.set_location(screen.w() - pad - beg_button.location().w, // screen.h() - pad - beg_button.location().h); events::raise_draw_event(); LOG_DP << "drew buttons dialog\n"; // draw logo over everything #ifdef __IPAD__ std::string path = game_config::path + "/data/core/images/misc/logo.png"; #else std::string path = game_config::path + "/data/core/images/misc/logo_small.png"; #endif surface logo_surface = IMG_Load(path.c_str()); //blit_surface(480-logo_surface.get()->w, 0, logo_surface); CKey key; size_t keyboard_button = nbuttons; bool key_processed = false; // update_whole_screen(); background_is_dirty_ = false; titlescreen_handler ts_handler(key[SDLK_ESCAPE] != 0); //!= 0 to avoid a MSVC warning C4800 LOG_DP << "entering interactive loop...\n"; memory_stats("At titlescreen"); // Initialize OpenFeint now of_init(); for(;;) { events::pump(); for(size_t b = 0; b != buttons.size(); ++b) { if(buttons[b].pressed()) { free_title(); return static_cast<TITLE_RESULT>(b + NEW_CAMPAIGN); } } /* if(previous_tip_button.pressed()) { next_tip_of_day(tips_of_day, true); draw_tip_of_day(screen, tips_of_day, gui::dialog_frame::titlescreen_style, &previous_tip_button, &next_tip_button, &help_tip_button, &main_dialog_area, tip_of_day_restorer); } if(next_tip_button.pressed()) { next_tip_of_day(tips_of_day, false); draw_tip_of_day(screen, tips_of_day, gui::dialog_frame::titlescreen_style, &previous_tip_button, &next_tip_button, &help_tip_button, &main_dialog_area, tip_of_day_restorer); } */ // if(help_tip_button.pressed()) { // return SHOW_HELP; // } // if(beg_button.pressed()) { // return BEG_FOR_UPLOAD; // } if (key[SDLK_UP]) { if (!key_processed) { buttons[keyboard_button].set_active(false); if (keyboard_button == 0) { keyboard_button = nbuttons - 1; } else { keyboard_button--; } key_processed = true; buttons[keyboard_button].set_active(true); } } else if (key[SDLK_DOWN]) { if (!key_processed) { buttons[keyboard_button].set_active(false); if (keyboard_button > nbuttons - 1) { keyboard_button = 0; } else { keyboard_button++; } key_processed = true; buttons[keyboard_button].set_active(true); } } else { key_processed = false; } events::raise_process_event(); // KP: redraw draw_background(screen); main_frame.draw_background(); main_frame.draw_border(); events::raise_draw_event(); //blit_surface(480-logo_surface.get()->w, 0, logo_surface); #ifdef __IPAD__ blit_surface(-10, 0, logo_surface); #else blit_surface(-15, -10, logo_surface); #endif screen.flip(); // if (key[SDLK_ESCAPE] && !ts_handler.get_esc_ignore()) // return QUIT_GAME; if (key[SDLK_F5]) return RELOAD_GAME_DATA; if (key[SDLK_RETURN] && keyboard_button < nbuttons) { return static_cast<TITLE_RESULT>(keyboard_button + NEW_CAMPAIGN); } // If the resolution has changed due to the user resizing the screen, // or from changing between windowed and fullscreen: if(screen.video().modeChanged()) { return REDRAW_BACKGROUND; } screen.delay(10); } free_title(); return REDRAW_BACKGROUND; }