/** Start the actual network thread. This can not be done as part of * the constructor, since the assignment to the global network_http * variable has not been assigned at that stage, and the thread might * use network_http - a very subtle race condition. So the thread can * only be started after the assignment (in main) has been done. * \pre PlayerManager was created and has read the main data for each * player so that all data for automatic login is * availale. */ void RequestManager::startNetworkThread() { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); // Should be the default, but just in case: pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); m_thread_id.setAtomic(new pthread_t()); int error = pthread_create(m_thread_id.getData(), &attr, &RequestManager::mainLoop, this); if (error) { m_thread_id.lock(); delete m_thread_id.getData(); m_thread_id.unlock(); m_thread_id.setAtomic(0); Log::error("HTTP Manager", "Could not create thread, error=%d.", errno); } pthread_attr_destroy(&attr); // In case that login id was not saved (or first start of stk), // current player would not be defined at this stage. PlayerProfile *player = PlayerManager::getCurrentPlayer(); if (player && player->wasOnlineLastTime() && !UserConfigParams::m_always_show_login_screen) { PlayerManager::resumeSavedSession(); } } // startNetworkThread
/** Make the entry fields either visible or invisible. * \param online Online state, which dicates if the entry fields are * visible (true) or not. */ void BaseUserScreen::makeEntryFieldsVisible() { #ifdef GUEST_ACCOUNTS_ENABLED getWidget<LabelWidget>("label_guest")->setVisible(online); getWidget<CheckBoxWidget>("guest")->setVisible(online); #endif bool online = m_online_cb->getState(); getWidget<LabelWidget>("label_username")->setVisible(online); m_username_tb->setVisible(online); getWidget<LabelWidget>("label_remember")->setVisible(online); getWidget<CheckBoxWidget>("remember-user")->setVisible(online); PlayerProfile *player = getSelectedPlayer(); if(player && player->hasSavedSession() && online) { // If we show the online login fields, but the player has a // saved session, don't show the password field. getWidget<LabelWidget>("label_password")->setVisible(false); m_password_tb->setVisible(false); } else { getWidget<LabelWidget>("label_password")->setVisible(online); m_password_tb->setVisible(online); } } // makeEntryFieldsVisible
/** Make the entry fields either visible or invisible. * \param online Online state, which dicates if the entry fields are * visible (true) or not. */ void BaseUserScreen::makeEntryFieldsVisible() { #ifdef GUEST_ACCOUNTS_ENABLED getWidget<LabelWidget>("label_guest")->setVisible(online); getWidget<CheckBoxWidget>("guest")->setVisible(online); #endif bool online = m_online_cb->getState(); getWidget<LabelWidget>("label_username")->setVisible(online); m_username_tb->setVisible(online); getWidget<LabelWidget>("label_remember")->setVisible(online); getWidget<CheckBoxWidget>("remember-user")->setVisible(online); PlayerProfile *player = getSelectedPlayer(); // Don't show the password fields if the player wants to be online // and either is the current player and logged in (no need to enter a // password then) or has a saved session. if(player && online && (player->hasSavedSession() || (player==PlayerManager::getCurrentPlayer() && player->isLoggedIn() ) ) ) { // If we show the online login fields, but the player has a // saved session, don't show the password field. getWidget<LabelWidget>("label_password")->setVisible(false); m_password_tb->setVisible(false); } else { getWidget<LabelWidget>("label_password")->setVisible(online); m_password_tb->setVisible(online); } } // makeEntryFieldsVisible
/** Called when a player will be deleted. */ void BaseUserScreen::deletePlayer() { // Check that there is at least one player left: we need to have a // valid current player, so the last player can not be deleted. if(PlayerManager::get()->getNumNonGuestPlayers()==1) { m_info_widget->setText("You can't delete the only player.", true); m_info_widget->setErrorColor(); return; } PlayerProfile *player = getSelectedPlayer(); irr::core::stringw message = //I18N: In the player info dialog (when deleting) _("Do you really want to delete player '%s' ?", player->getName(true/*ignoreRTL*/)); class ConfirmServer : public MessageDialog::IConfirmDialogListener { BaseUserScreen *m_parent_screen; public: virtual void onConfirm() { m_parent_screen->doDeletePlayer(); } // onConfirm // ------------------------------------------------------------ ConfirmServer(BaseUserScreen *parent) { m_parent_screen = parent; } }; // ConfirmServer new MessageDialog(message, MessageDialog::MESSAGE_DIALOG_CONFIRM, new ConfirmServer(this), true); } // deletePlayer
/** This function makes sure that a current player is defined. This is called * when a screen skipping command line option is given (-N, -R, ...), in * which case there might not be a current player (if no default player is * set in players.xml, i.e. the 'remember be' option was not picked ). Since * a lot of code depends on having a local player, just set the most * frequently used non-guest to be the current player. */ void PlayerManager::enforceCurrentPlayer() { if (m_current_player) return; PlayerProfile* player; for_in(player, m_all_players) { if (!player->isGuestAccount()) { Log::info("PlayerManager", "Enfocring current player '%ls'.", player->getName().c_str() ); m_current_player = player; return; } } // for player in m_all_players // This shouldn't happen - but just in case: add the default players // again, and search again for a non-guest player. addDefaultPlayer(); for_in(player, m_all_players) { if (!player->isGuestAccount()) { Log::info("PlayerManager", "Enfocring current player '%s'.", player->getName().c_str()); m_current_player = player; return; } } // for player in m_all_players // Now this really really should not happen. Log::fatal("PlayerManager", "Failed to find a non-guest player."); } // enforceCurrentPlayer
// ---------------------------------------------------------------------------- void MainMenuScreen::onUpdate(float delta) { PlayerProfile *player = PlayerManager::getCurrentPlayer(); if(PlayerManager::getCurrentOnlineState() == PlayerProfile::OS_GUEST || PlayerManager::getCurrentOnlineState() == PlayerProfile::OS_SIGNED_IN) { m_user_id->setText(player->getLastOnlineName() + "@stk"); m_online->setActivated(); m_online->setLabel( _("Online")); } else if (PlayerManager::getCurrentOnlineState() == PlayerProfile::OS_SIGNED_OUT) { m_online->setActivated(); m_online->setLabel( _("Login" )); m_user_id->setText(player->getName()); } else { // now must be either logging in or logging out m_online->setDeactivated(); m_user_id->setText(player->getName()); } m_online->setLabel(PlayerManager::getCurrentOnlineId() ? _("Online") : _("Login" ) ); IconButtonWidget* addons_icon = getWidget<IconButtonWidget>("addons"); if (addons_icon != NULL) { if (addons_manager->wasError()) { addons_icon->setActivated(); addons_icon->resetAllBadges(); addons_icon->setBadge(BAD_BADGE); } else if (addons_manager->isLoading() && UserConfigParams::m_internet_status == Online::RequestManager::IPERM_ALLOWED) { // Addons manager is still initialising/downloading. addons_icon->setDeactivated(); addons_icon->resetAllBadges(); addons_icon->setBadge(LOADING_BADGE); } else { addons_icon->setActivated(); addons_icon->resetAllBadges(); } // maybe add a new badge when not allowed to access the net } LabelWidget* w = getWidget<LabelWidget>("info_addons"); w->update(delta); if(w->scrolledOff()) { const core::stringw &news_text = NewsManager::get()->getNextNewsMessage(); w->setText(news_text, true); } } // onUpdate
/** Callback from player profile if login was successful. */ void BaseUserScreen::loginSuccessful() { PlayerProfile *player = getSelectedPlayer(); player->setWasOnlineLastTime(true); m_options_widget->setActive(true); // Clean any error message still shown m_info_widget->setText("", true); m_info_widget->setErrorColor(); // The callback is done from the main thread, so no need to sync // access to m_success. OnUpdate will check this flag closeScreen(); } // loginSuccessful
/** Callback from player profile if login was unsuccessful. * \param error_message Contains the error message. */ void BaseUserScreen::logoutError(const irr::core::stringw & error_message) { m_state = (UserScreenState) (m_state & ~STATE_LOGOUT); PlayerProfile *player = getSelectedPlayer(); // Clear information about saved session in case of a problem, // which allows the player to enter a new password. if(player && player->hasSavedSession()) player->clearSession(); makeEntryFieldsVisible(); SFXManager::get()->quickSound("anvil"); m_info_widget->setErrorColor(); m_info_widget->setText(error_message, false); m_options_widget->setActive(true); } // logoutError
// ---------------------------------------------------------------------------- bool KartProperties::operator<(const KartProperties &other) const { PlayerProfile *p = PlayerManager::getCurrentPlayer(); bool this_is_locked = p->isLocked(getIdent()); bool other_is_locked = p->isLocked(other.getIdent()); if (this_is_locked == other_is_locked) { return getName() < other.getName(); } else return other_is_locked; return true; } // operator<
void OptionsScreenPlayers::eventCallback(Widget* widget, const std::string& name, const int playerID) { if (name == "options_choice") { std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str(); if (selection == "tab_audio") StateManager::get()->replaceTopMostScreen(OptionsScreenAudio::getInstance()); else if (selection == "tab_video") StateManager::get()->replaceTopMostScreen(OptionsScreenVideo::getInstance()); else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(OptionsScreenPlayers::getInstance()); else if (selection == "tab_controls") StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance()); else if (selection == "tab_ui") StateManager::get()->replaceTopMostScreen(OptionsScreenUI::getInstance()); } else if (name == "back") { StateManager::get()->escapePressed(); } else if (name == "addplayer") { new EnterPlayerNameDialog(this, 0.5f, 0.4f); } else if (name == "players") { // Find which player in the list was clicked ListWidget* players = this->getWidget<ListWidget>("players"); assert(players != NULL); core::stringw selectedPlayer = players->getSelectionLabel(); const int player_amount = PlayerManager::get()->getNumPlayers(); for (int i=0; i<player_amount; i++) { PlayerProfile *player = PlayerManager::get()->getPlayer(i); if (selectedPlayer == translations->fribidize(player->getName())) { if (!(player->isGuestAccount())) { new PlayerInfoDialog( player, 0.5f, 0.6f ); } return; } } // end for } else if (name == "playername") { race_manager->clearKartLastPositionOnOverworld(); PlayerManager::get()->setCurrentPlayer(NULL,false); StateManager::get()->pushScreen(StoryModeLobbyScreen::getInstance()); } } // eventCallback
void FeatureUnlockedCutScene::findWhatWasUnlocked(RaceManager::Difficulty difficulty) { PlayerProfile *player = PlayerManager::getCurrentPlayer(); int points_before = player->getPoints(); int points_now = points_before + CHALLENGE_POINTS[difficulty]; std::vector<std::string> tracks; std::vector<std::string> gps; player->computeActive(); unlock_manager->findWhatWasUnlocked(points_before, points_now, tracks, gps); for (unsigned int i = 0; i < tracks.size(); i++) { addUnlockedTrack(track_manager->getTrack(tracks[i])); } for (unsigned int i = 0; i < gps.size(); i++) { addUnlockedGP(grand_prix_manager->getGrandPrix(gps[i])); } }
/** Callback when the user confirms to delete a player. This function actually * deletes the player, discards the dialog, and re-initialised the BaseUserScreen * to display only the available players. */ void BaseUserScreen::doDeletePlayer() { PlayerProfile *player = getSelectedPlayer(); PlayerManager::get()->deletePlayer(player); GUIEngine::ModalDialog::dismiss(); // Special case: the current player was deleted. We have to make sure // that there is still a current player (all of STK depends on that). if(!PlayerManager::getCurrentPlayer()) { for(unsigned int i=0; i<PlayerManager::get()->getNumPlayers(); i++) { PlayerProfile *player = PlayerManager::get()->getPlayer(i); if(!player->isGuestAccount()) { PlayerManager::get()->setCurrentPlayer(player); break; } } } init(); } // doDeletePlayer
/** Called once every frame. It will replace this screen with the main menu * screen if a successful login happened. */ void BaseUserScreen::onUpdate(float dt) { if (!m_options_widget->isActivated()) { core::stringw message = (m_state & STATE_LOGOUT) ? _(L"Signing out '%s'",m_sign_out_name.c_str()) : _(L"Signing in '%s'", m_sign_in_name.c_str()); m_info_widget->setText(StringUtils::loadingDots(message.c_str()), false ); } PlayerProfile *player = getSelectedPlayer(); if(player) { // If the player changes the online name, clear the saved session // flag, and make the password field visible again. if (m_username_tb->getText()!=player->getLastOnlineName()) { player->clearSession(); makeEntryFieldsVisible(); } } } // onUpdate
/** Called when a user is selected. It updates the online checkbox and * entry fields. */ void BaseUserScreen::selectUser(int index) { PlayerProfile *profile = PlayerManager::get()->getPlayer(index); assert(profile); // Only set focus in case of non-tabbed version (so that keyboard // or gamepad navigation with tabs works as expected, i.e. you can // select the next tab without having to go up to the tab list first. bool focus_it = !getWidget<RibbonWidget>("options_choice"); m_players->setSelection(StringUtils::toString(index), PLAYER_ID_GAME_MASTER, focus_it); if (!m_new_registered_data) m_username_tb->setText(profile->getLastOnlineName(true/*ignoreRTL*/)); if (!m_new_registered_data) { // Delete a password that might have been typed for another user m_password_tb->setText(""); } getWidget<CheckBoxWidget>("remember-user")->setState( profile->rememberPassword()); // Last game was not online, so make the offline settings the default // (i.e. unckeck online checkbox, and make entry fields invisible). if (!profile->wasOnlineLastTime() || profile->getLastOnlineName() == "") { if (!m_new_registered_data) m_online_cb->setState(false); makeEntryFieldsVisible(); return; } // Now last use was with online --> Display the saved data if (UserConfigParams::m_internet_status == Online::RequestManager::IPERM_NOT_ALLOWED) m_online_cb->setState(false); else m_online_cb->setState(true); makeEntryFieldsVisible(); m_username_tb->setActive(profile->getLastOnlineName().size() == 0); // And make the password invisible if the session is saved (i.e // the user does not need to enter a password). if (profile->hasSavedSession()) { m_password_tb->setVisible(false); getWidget<LabelWidget>("label_password")->setVisible(false); getWidget<ButtonWidget>("password_reset")->setVisible(false); } } // selectUser
/** Called when a user is selected. It updates the online checkbox and * entrye fields. */ void BaseUserScreen::selectUser(int index) { PlayerProfile *profile = PlayerManager::get()->getPlayer(index); assert(profile); m_players->setSelection(StringUtils::toString(index), PLAYER_ID_GAME_MASTER, /*focusIt*/ true); m_username_tb->setText(profile->getLastOnlineName()); // Delete a password that might have been typed for another user m_password_tb->setText(""); // Last game was not online, so make the offline settings the default // (i.e. unckeck online checkbox, and make entry fields invisible). if (!profile->wasOnlineLastTime() || profile->getLastOnlineName() == "") { m_online_cb->setState(false); makeEntryFieldsVisible(); return; } // Now last use was with online --> Display the saved data m_online_cb->setState(true); makeEntryFieldsVisible(); getWidget<CheckBoxWidget>("remember-user")->setState( profile->rememberPassword()); if(profile->getLastOnlineName().size()>0) m_username_tb->setDeactivated(); else m_username_tb->setActivated(); // And make the password invisible if the session is saved (i.e // the user does not need to enter a password). if (profile->hasSavedSession()) { m_password_tb->setVisible(false); getWidget<LabelWidget>("label_password")->setVisible(false); } } // selectUser
void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, const int playerID) { if(name=="user-id") { UserScreen::getInstance()->push(); return; } // most interesting stuff is in the ribbons, so start there RibbonWidget* ribbon = dynamic_cast<RibbonWidget*>(widget); if (ribbon == NULL) return; // what's that event?? // ---- A ribbon icon was clicked std::string selection = ribbon->getSelectionIDString(PLAYER_ID_GAME_MASTER); /* if (selection == "story") { StateManager::get()->enterGameState(); race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE); race_manager->setNumKarts( 0 ); race_manager->setNumPlayers(0); race_manager->setNumPlayers(0); race_manager->startSingleRace("endcutscene", 999, false); std::vector<std::string> parts; parts.push_back("introcutscene"); parts.push_back("introcutscene2"); ((CutsceneWorld*)World::getWorld())->setParts(parts); //race_manager->startSingleRace("introcutscene2", 999, false); return; } */ #if DEBUG_MENU_ITEM if (selection == "test_gpwin") { StoryModeStatus* sms = PlayerManager::getCurrentPlayer()->getStoryModeStatus(); sms->unlockFeature(const_cast<ChallengeStatus*>(sms->getChallengeStatus("gp1")), RaceManager::DIFFICULTY_HARD); StateManager::get()->enterGameState(); race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE); race_manager->setNumKarts(0); race_manager->setNumPlayers(0); race_manager->setNumPlayers(0); race_manager->startSingleRace("gpwin", 999, false); GrandPrixWin* scene = GrandPrixWin::getInstance(); scene->push(); const std::string winners[] = { "kiki", "nolok", "pidgin" }; scene->setKarts(winners); } else if (selection == "test_gplose") { StateManager::get()->enterGameState(); race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE); race_manager->setNumKarts(0); race_manager->setNumPlayers(0); race_manager->setNumPlayers(0); race_manager->startSingleRace("gplose", 999, false); GrandPrixLose* scene = GrandPrixLose::getInstance(); scene->push(); std::vector<std::string> losers; losers.push_back("nolok"); losers.push_back("kiki"); //losers.push_back("wilber"); //losers.push_back("tux"); scene->setKarts(losers); } else if (selection == "test_unlocked" || selection == "test_unlocked2") { StoryModeStatus* sms = PlayerManager::getCurrentPlayer()->getStoryModeStatus(); sms->unlockFeature(const_cast<ChallengeStatus*>(sms->getChallengeStatus("gp1")), RaceManager::DIFFICULTY_HARD); StateManager::get()->enterGameState(); race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE); race_manager->setNumKarts(0); race_manager->setNumPlayers(0); race_manager->setNumPlayers(0); race_manager->startSingleRace("featunlocked", 999, false); FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance(); std::vector<std::string> parts; parts.push_back("featunlocked"); ((CutsceneWorld*)World::getWorld())->setParts(parts); scene->addTrophy(RaceManager::DIFFICULTY_EASY); if (selection == "test_unlocked") { // the passed kart will not be modified, that's why I allow myself // to use const_cast scene->addUnlockedKart( const_cast<KartProperties*>( kart_properties_manager->getKart("tux") ), L"You unlocked <actual text would go here...>" ); scene->addUnlockedTrack(track_manager->getTrack("lighthouse")); scene->push(); } else if (selection == "test_unlocked2") { std::vector<video::ITexture*> textures; textures.push_back(irr_driver->getTexture( track_manager->getTrack("lighthouse") ->getScreenshotFile().c_str())); textures.push_back(irr_driver->getTexture( track_manager->getTrack("snowtuxpeak") ->getScreenshotFile().c_str())); textures.push_back(irr_driver->getTexture( track_manager->getTrack("sandtrack") ->getScreenshotFile().c_str())); textures.push_back(irr_driver->getTexture( track_manager->getTrack("snowmountain") ->getScreenshotFile().c_str())); scene->addUnlockedPictures(textures, 4.0, 3.0, L"You unlocked <actual text would go here...>"); scene->push(); } } else if (selection == "test_intro") { CutsceneWorld::setUseDuration(true); StateManager::get()->enterGameState(); race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE); race_manager->setNumKarts(0); race_manager->setNumPlayers(0); race_manager->setNumPlayers(0); race_manager->startSingleRace("introcutscene", 999, false); std::vector<std::string> parts; parts.push_back("introcutscene"); parts.push_back("introcutscene2"); ((CutsceneWorld*)World::getWorld())->setParts(parts); //race_manager->startSingleRace("introcutscene2", 999, false); return; } else if (selection == "test_outro") { CutsceneWorld::setUseDuration(true); StateManager::get()->enterGameState(); race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE); race_manager->setNumKarts(0); race_manager->setNumPlayers(0); race_manager->setNumPlayers(0); race_manager->startSingleRace("endcutscene", 999, false); std::vector<std::string> parts; parts.push_back("endcutscene"); ((CutsceneWorld*)World::getWorld())->setParts(parts); } else #endif if (selection == "new") { NetworkConfig::get()->unsetNetworking(); KartSelectionScreen* s = OfflineKartSelectionScreen::getInstance(); s->setMultiplayer(false); s->setFromOverworld(false); s->push(); } else if (selection == "multiplayer") { KartSelectionScreen* s = OfflineKartSelectionScreen::getInstance(); NetworkConfig::get()->unsetNetworking(); s->setMultiplayer(true); s->setFromOverworld(false); s->push(); } else if (selection == "options") { OptionsScreenVideo::getInstance()->push(); } else if (selection == "quit") { StateManager::get()->popMenu(); return; } else if (selection == "about") { CreditsScreen::getInstance()->push(); } else if (selection == "help") { HelpScreen1::getInstance()->push(); } else if (selection == "startTutorial") { race_manager->setNumPlayers(1); race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE); race_manager->setMinorMode (RaceManager::MINOR_MODE_TUTORIAL); race_manager->setNumKarts( 1 ); race_manager->setTrack( "tutorial" ); race_manager->setDifficulty(RaceManager::DIFFICULTY_EASY); race_manager->setReverseTrack(false); // Use keyboard 0 by default (FIXME: let player choose?) InputDevice* device = input_manager->getDeviceManager()->getKeyboard(0); // Create player and associate player with keyboard StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(), device); if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL) { Log::warn("MainMenuScreen", "Cannot find kart '%s', will revert to default", UserConfigParams::m_default_kart.c_str()); UserConfigParams::m_default_kart.revertToDefaults(); } race_manager->setPlayerKart(0, UserConfigParams::m_default_kart); // ASSIGN should make sure that only input from assigned devices // is read. input_manager->getDeviceManager()->setAssignMode(ASSIGN); input_manager->getDeviceManager() ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); StateManager::get()->enterGameState(); race_manager->setupPlayerKartInfo(); race_manager->startNew(false); } else if (selection == "story") { NetworkConfig::get()->unsetNetworking(); PlayerProfile *player = PlayerManager::getCurrentPlayer(); if (player->isFirstTime()) { CutsceneWorld::setUseDuration(true); StateManager::get()->enterGameState(); race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE); race_manager->setNumKarts( 0 ); race_manager->setNumPlayers(0); race_manager->startSingleRace("introcutscene", 999, false); std::vector<std::string> parts; parts.push_back("introcutscene"); parts.push_back("introcutscene2"); ((CutsceneWorld*)World::getWorld())->setParts(parts); //race_manager->startSingleRace("introcutscene2", 999, false); return; } else { const std::string default_kart = UserConfigParams::m_default_kart; if (player->isLocked(default_kart)) { KartSelectionScreen *next = OfflineKartSelectionScreen::getInstance(); next->setGoToOverworldNext(); next->setMultiplayer(false); StateManager::get()->resetAndGoToScreen(next); return; } OverWorld::enterOverWorld(); } } else if (selection == "online") { if(UserConfigParams::m_internet_status!=RequestManager::IPERM_ALLOWED) { new MessageDialog(_("You can not play online without internet access. " "If you want to play online, go to options, select " " tab 'User Interface', and edit " "\"Connect to the Internet\".")); return; } // Define this to require a login to the stk server (default behaviour) // Undefine for testing LAN only. if (MainMenuScreen::m_enable_online) { OnlineScreen::getInstance()->push(); } else { if (PlayerManager::getCurrentOnlineId()) { ProfileManager::get()->setVisiting(PlayerManager::getCurrentOnlineId()); TabOnlineProfileAchievements::getInstance()->push(); } else { UserScreen::getInstance()->push(); } } } else if (selection == "addons") { // Don't go to addons if there is no internet, unless some addons are // already installed (so that you can delete addons without being online). if(UserConfigParams::m_internet_status!=RequestManager::IPERM_ALLOWED && !addons_manager->anyAddonsInstalled()) { new MessageDialog(_("You can not download addons without internet access. " "If you want to download addons, go to options, select " " tab 'User Interface', and edit " "\"Connect to the Internet\".")); return; } AddonsScreen::getInstance()->push(); } else if (selection == "gpEditor") { GrandPrixEditorScreen::getInstance()->push(); } else if (selection == "achievements") { OnlineProfileAchievements::getInstance()->push(); } } // eventCallback
/** Is called by check structures if a kart starts a new lap. * \param kart_index Index of the kart. */ void LinearWorld::newLap(unsigned int kart_index) { KartInfo &kart_info = m_kart_info[kart_index]; AbstractKart *kart = m_karts[kart_index]; // Reset reset-after-lap achievements StateManager::ActivePlayer *c = kart->getController()->getPlayer(); PlayerProfile *p = PlayerManager::getCurrentPlayer(); if (c && c->getConstProfile() == p) { p->getAchievementsStatus()->onLapEnd(); } // Only update the kart controller if a kart that has already finished // the race crosses the start line again. This avoids 'fastest lap' // messages if the end controller does a fastest lap, but especially // allows the end controller to switch end cameras if(kart->hasFinishedRace()) { kart->getController()->newLap(kart_info.m_race_lap); return; } const int lap_count = race_manager->getNumLaps(); // Only increase the lap counter and set the new time if the // kart hasn't already finished the race (otherwise the race_gui // will begin another countdown). if(kart_info.m_race_lap+1 <= lap_count) { assert(kart->getWorldKartId()==kart_index); kart_info.m_time_at_last_lap=getTime(); kart_info.m_race_lap++; m_kart_info[kart_index].m_overall_distance = m_kart_info[kart_index].m_race_lap * m_track->getTrackLength() + getDistanceDownTrackForKart(kart->getWorldKartId()); } // Last lap message (kart_index's assert in previous block already) if (raceHasLaps() && kart_info.m_race_lap+1 == lap_count) { m_race_gui->addMessage(_("Final lap!"), kart, 3.0f, video::SColor(255, 210, 100, 50), true); if(!m_last_lap_sfx_played && lap_count > 1) { if (UserConfigParams::m_music) { m_last_lap_sfx->play(); m_last_lap_sfx_played = true; m_last_lap_sfx_playing = true; // In case that no music is defined if(music_manager->getCurrentMusic() && music_manager->getMasterMusicVolume() > 0.2f) { music_manager->setTemporaryVolume(0.2f); } } else { m_last_lap_sfx_played = true; m_last_lap_sfx_playing = false; } } } else if (raceHasLaps() && kart_info.m_race_lap > 0 && kart_info.m_race_lap+1 < lap_count) { m_race_gui->addMessage(_("Lap %i", kart_info.m_race_lap+1), kart, 3.0f, video::SColor(255, 210, 100, 50), true); } // The race positions must be updated here: consider the situation where // the first kart does not cross the finish line in its last lap, instead // it passes it, the kart reverses and crosses the finishing line // backwards. Just before crossing the finishing line the kart will be on // the last lap, but with a distance along the track close to zero. // Therefore its position will be wrong. If the race position gets updated // after increasing the number of laps (but before tagging the kart to have // finished the race) the position will be correct (since the kart now // has one additional lap it will be ahead of the other karts). // Without this call the incorrect position for this kart would remain // (since a kart that has finished the race does not get its position // changed anymore), potentially resulting in a duplicated race position // (since the first kart does not have position 1, no other kart can get // position 1, so one rank will be duplicated). // Similarly the situation can happen if the distance along track should // go back to zero before actually crossing the finishing line. While this // should not happen, it could potentially be caused by floating point // errors. In this case the call to updateRacePosition will avoid // duplicated race positions as well. updateRacePosition(); // Race finished if(kart_info.m_race_lap >= race_manager->getNumLaps() && raceHasLaps()) { kart->finishedRace(getTime()); } float time_per_lap; if (kart_info.m_race_lap == 1) // just completed first lap { time_per_lap=getTime(); } else //completing subsequent laps { time_per_lap=getTime() - kart_info.m_lap_start_time; } // if new fastest lap if(time_per_lap < m_fastest_lap && raceHasLaps() && kart_info.m_race_lap>0) { m_fastest_lap = time_per_lap; std::string s = StringUtils::timeToString(time_per_lap); // Store the temporary string because clang would mess this up // (remove the stringw before the wchar_t* is used). const core::stringw &kart_name = kart->getName(); //I18N: as in "fastest lap: 60 seconds by Wilber" irr::core::stringw m_fastest_lap_message = _C("fastest_lap", "%s by %s", s.c_str(), kart_name); m_race_gui->addMessage(m_fastest_lap_message, NULL, 3.0f, video::SColor(255, 255, 255, 255), false); m_race_gui->addMessage(_("New fastest lap"), NULL, 3.0f, video::SColor(255, 255, 255, 255), false); } // end if new fastest lap kart_info.m_lap_start_time = getTime(); kart->getController()->newLap(kart_info.m_race_lap); } // newLap
void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, const int playerID) { if (name == "options_choice") { std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); Screen *screen = NULL; if (selection == "tab_audio") screen = OptionsScreenAudio::getInstance(); else if (selection == "tab_video") screen = OptionsScreenVideo::getInstance(); else if (selection == "tab_players") screen = TabbedUserScreen::getInstance(); else if (selection == "tab_controls") screen = OptionsScreenInput::getInstance(); //else if (selection == "tab_ui") // screen = OptionsScreenUI::getInstance(); if(screen) StateManager::get()->replaceTopMostScreen(screen); } else if(name == "back") { StateManager::get()->escapePressed(); } else if (name == "skinchoice") { GUIEngine::SpinnerWidget* skinSelector = getWidget<GUIEngine::SpinnerWidget>("skinchoice"); assert( skinSelector != NULL ); const core::stringw selectedSkin = skinSelector->getStringValue(); UserConfigParams::m_skin_file = core::stringc(selectedSkin.c_str()).c_str() + std::string(".stkskin"); GUIEngine::reloadSkin(); } else if (name == "showfps") { CheckBoxWidget* fps = getWidget<CheckBoxWidget>("showfps"); assert( fps != NULL ); UserConfigParams::m_display_fps = fps->getState(); } else if (name=="enable-internet") { CheckBoxWidget* internet = getWidget<CheckBoxWidget>("enable-internet"); assert( internet != NULL ); UserConfigParams::m_internet_status = internet->getState() ? RequestManager::IPERM_ALLOWED : RequestManager::IPERM_NOT_ALLOWED; // If internet gets enabled, re-initialise the addon manager (which // happens in a separate thread) so that news.xml etc can be // downloaded if necessary. CheckBoxWidget *stats = getWidget<CheckBoxWidget>("enable-hw-report"); LabelWidget *stats_label = getWidget<LabelWidget>("label-hw-report"); if(internet->getState()) { NewsManager::get()->init(false); stats->setVisible(true); stats_label->setVisible(true); stats->setState(UserConfigParams::m_hw_report_enable); } else { stats->setVisible(false); stats_label->setVisible(false); PlayerProfile* profile = PlayerManager::getCurrentPlayer(); if (profile != NULL && profile->isLoggedIn()) profile->requestSignOut(); } } else if (name=="enable-hw-report") { CheckBoxWidget* stats = getWidget<CheckBoxWidget>("enable-hw-report"); UserConfigParams::m_hw_report_enable = stats->getState(); if(stats->getState()) HardwareStats::reportHardwareStats(); } else if (name=="show-login") { CheckBoxWidget* show_login = getWidget<CheckBoxWidget>("show-login"); assert( show_login != NULL ); UserConfigParams::m_always_show_login_screen = show_login->getState(); } else if (name=="perPlayerDifficulty") { CheckBoxWidget* difficulty = getWidget<CheckBoxWidget>("perPlayerDifficulty"); assert( difficulty != NULL ); UserConfigParams::m_per_player_difficulty = difficulty->getState(); } else if (name == "language") { ListWidget* list_widget = getWidget<ListWidget>("language"); std::string selection = list_widget->getSelectionInternalName(); delete translations; if (selection == "system") { #ifdef WIN32 _putenv("LANGUAGE="); #else unsetenv("LANGUAGE"); #endif } else { #ifdef WIN32 std::string s=std::string("LANGUAGE=")+selection.c_str(); _putenv(s.c_str()); #else setenv("LANGUAGE", selection.c_str(), 1); #endif } translations = new Translations(); // Reload fonts for new translation GUIEngine::getStateManager()->hardResetAndGoToScreen<MainMenuScreen>(); font_manager->getFont<BoldFace>()->reset(); font_manager->getFont<RegularFace>()->reset(); GUIEngine::getFont()->updateRTL(); GUIEngine::getTitleFont()->updateRTL(); GUIEngine::getSmallFont()->updateRTL(); GUIEngine::getLargeFont()->updateRTL(); GUIEngine::getOutlineFont()->updateRTL(); UserConfigParams::m_language = selection.c_str(); user_config->saveConfig(); OptionsScreenUI::getInstance()->push(); } } // eventCallback
/** Displays the number of challenge trophies */ void RaceGUIOverworld::drawTrophyPoints() { PlayerProfile *player = PlayerManager::get()->getCurrentPlayer(); const int points = player->getPoints(); std::string s = StringUtils::toString(points); core::stringw sw(s.c_str()); static video::SColor time_color = video::SColor(255, 255, 255, 255); int dist_from_right = 10 + m_trophy_points_width; core::rect<s32> pos(UserConfigParams::m_width - dist_from_right, 10, UserConfigParams::m_width , 50); bool vcenter = false; gui::ScalableFont* font = GUIEngine::getFont(); vcenter = true; const int size = UserConfigParams::m_width/20; core::rect<s32> dest(size, pos.UpperLeftCorner.Y, size*2, pos.UpperLeftCorner.Y + size); core::rect<s32> source(core::position2di(0, 0), m_trophy3->getSize()); font->setShadow(video::SColor(255,0,0,0)); if (!m_close_to_a_challenge) { draw2DImage(m_trophy1, dest, source, NULL, NULL, true /* alpha */); } dest += core::position2di((int)(size*1.5f), 0); std::string easyTrophies = StringUtils::toString(player->getNumEasyTrophies()); core::stringw easyTrophiesW(easyTrophies.c_str()); if (!m_close_to_a_challenge) { font->draw(easyTrophiesW.c_str(), dest, time_color, false, vcenter, NULL, true /* ignore RTL */); } dest += core::position2di(size*2, 0); if (!m_close_to_a_challenge) { draw2DImage(m_trophy2, dest, source, NULL, NULL, true /* alpha */); } dest += core::position2di((int)(size*1.5f), 0); std::string mediumTrophies = StringUtils::toString(player->getNumMediumTrophies()); core::stringw mediumTrophiesW(mediumTrophies.c_str()); if (!m_close_to_a_challenge) { font->draw(mediumTrophiesW.c_str(), dest, time_color, false, vcenter, NULL, true /* ignore RTL */); } dest += core::position2di(size*2, 0); if (!m_close_to_a_challenge) { draw2DImage(m_trophy3, dest, source, NULL, NULL, true /* alpha */); } dest += core::position2di((int)(size*1.5f), 0); std::string hardTrophies = StringUtils::toString(player->getNumHardTrophies()); core::stringw hardTrophiesW(hardTrophies.c_str()); if (!m_close_to_a_challenge) { font->draw(hardTrophiesW.c_str(), dest, time_color, false, vcenter, NULL, true /* ignore RTL */); } dest = core::rect<s32>(pos.UpperLeftCorner.X - size - 5, pos.UpperLeftCorner.Y, pos.UpperLeftCorner.X - 5, pos.UpperLeftCorner.Y + size); draw2DImage(m_open_challenge, dest, source, NULL, NULL, true /* alpha */); pos.LowerRightCorner.Y = dest.LowerRightCorner.Y; pos.UpperLeftCorner.X += 5; font->draw(sw.c_str(), pos, time_color, false, vcenter, NULL, true /* ignore RTL */); font->disableShadow(); } // drawTrophyPoints
void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, const int playerID) { // most interesting stuff is in the ribbons, so start there RibbonWidget* ribbon = dynamic_cast<RibbonWidget*>(widget); if (ribbon == NULL) return; // what's that event?? // ---- A ribbon icon was clicked std::string selection = ribbon->getSelectionIDString(PLAYER_ID_GAME_MASTER); /* if (selection == "story") { StateManager::get()->enterGameState(); race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE); race_manager->setNumKarts( 0 ); race_manager->setNumPlayers(0); race_manager->setNumLocalPlayers(0); race_manager->startSingleRace("endcutscene", 999, false); std::vector<std::string> parts; parts.push_back("introcutscene"); parts.push_back("introcutscene2"); ((CutsceneWorld*)World::getWorld())->setParts(parts); //race_manager->startSingleRace("introcutscene2", 999, false); return; } */ #if DEBUG_MENU_ITEM if (selection == "options") { // The DEBUG item FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance(); scene->addTrophy(RaceManager::DIFFICULTY_EASY); StateManager::get()->pushScreen(scene); /* static int i = 1; i++; if (i % 4 == 0) { // the passed kart will not be modified, that's why I allow myself // to use const_cast scene->addUnlockedKart( const_cast<KartProperties*>( kart_properties_manager->getKart("tux") ), L"Unlocked" ); StateManager::get()->pushScreen(scene); } else if (i % 4 == 1) { std::vector<video::ITexture*> textures; textures.push_back(irr_driver->getTexture( track_manager->getTrack("lighthouse") ->getScreenshotFile().c_str())); textures.push_back(irr_driver->getTexture( track_manager->getTrack("crescentcrossing") ->getScreenshotFile().c_str())); textures.push_back(irr_driver->getTexture( track_manager->getTrack("sandtrack") ->getScreenshotFile().c_str())); textures.push_back(irr_driver->getTexture( track_manager->getTrack("snowmountain") ->getScreenshotFile().c_str())); scene->addUnlockedPictures(textures, 1.0, 0.75, L"You did it"); StateManager::get()->pushScreen(scene); } else if (i % 4 == 2) { GrandPrixWin* scene = GrandPrixWin::getInstance(); const std::string winners[] = { "elephpant", "nolok", "pidgin" }; StateManager::get()->pushScreen(scene); scene->setKarts( winners ); } else { GrandPrixLose* scene = GrandPrixLose::getInstance(); StateManager::get()->pushScreen(scene); std::vector<std::string> losers; losers.push_back("nolok"); losers.push_back("elephpant"); losers.push_back("wilber"); scene->setKarts( losers ); } */ } else #endif if (selection == "new") { KartSelectionScreen* s = OfflineKartSelectionScreen::getInstance(); //FIXME : that was for tests s->setMultiplayer(false); s->setFromOverworld(false); StateManager::get()->pushScreen( s ); } else if (selection == "multiplayer") { KartSelectionScreen* s = OfflineKartSelectionScreen::getInstance(); s->setMultiplayer(true); s->setFromOverworld(false); StateManager::get()->pushScreen( s ); } else if (selection == "options") { StateManager::get()->pushScreen( OptionsScreenVideo::getInstance() ); } else if (selection == "quit") { StateManager::get()->popMenu(); return; } else if (selection == "about") { StateManager::get()->pushScreen(CreditsScreen::getInstance()); } else if (selection == "help") { StateManager::get()->pushScreen(HelpScreen1::getInstance()); } else if (selection == "startTutorial") { race_manager->setNumLocalPlayers(1); race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE); race_manager->setMinorMode (RaceManager::MINOR_MODE_TUTORIAL); race_manager->setNumKarts( 1 ); race_manager->setTrack( "tutorial" ); race_manager->setDifficulty(RaceManager::DIFFICULTY_EASY); race_manager->setReverseTrack(false); // Use keyboard 0 by default (FIXME: let player choose?) InputDevice* device = input_manager->getDeviceList()->getKeyboard(0); // Create player and associate player with keyboard StateManager::get()->createActivePlayer(PlayerManager::get()->getCurrentPlayer(), device, NULL); if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL) { fprintf(stderr, "[MainMenuScreen] WARNING: cannot find kart '%s', will revert to default\n", UserConfigParams::m_default_kart.c_str()); UserConfigParams::m_default_kart.revertToDefaults(); } race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart); // ASSIGN should make sure that only input from assigned devices // is read. input_manager->getDeviceList()->setAssignMode(ASSIGN); input_manager->getDeviceList() ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); StateManager::get()->enterGameState(); race_manager->setupPlayerKartInfo(); race_manager->startNew(false); } else if (selection == "story") { PlayerProfile *player = PlayerManager::get()->getCurrentPlayer(); if (player->isFirstTime()) { StateManager::get()->enterGameState(); race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE); race_manager->setNumKarts( 0 ); race_manager->setNumPlayers(0); race_manager->setNumLocalPlayers(0); race_manager->startSingleRace("introcutscene", 999, false); std::vector<std::string> parts; parts.push_back("introcutscene"); parts.push_back("introcutscene2"); ((CutsceneWorld*)World::getWorld())->setParts(parts); //race_manager->startSingleRace("introcutscene2", 999, false); return; } else { const std::string default_kart = UserConfigParams::m_default_kart; if (player->isLocked(default_kart)) { KartSelectionScreen *next = OfflineKartSelectionScreen::getInstance(); next->setGoToOverworldNext(); next->setMultiplayer(false); StateManager::get()->resetAndGoToScreen(next); return; } OverWorld::enterOverWorld(); } } else if (selection == "online") { if(UserConfigParams::m_internet_status!=RequestManager::IPERM_ALLOWED) { new MessageDialog(_("You can not play online without internet access. " "If you want to play online, go to options, select " " tab 'User Interface', and edit " "\"Allow STK to connect to the Internet\".")); return; } if(CurrentUser::get()->getID()) StateManager::get()->pushScreen(OnlineScreen::getInstance()); else StateManager::get()->pushScreen(LoginScreen::getInstance()); } else if (selection == "addons") { // Don't go to addons if there is no internet, unless some addons are // already installed (so that you can delete addons without being online). if(UserConfigParams::m_internet_status!=RequestManager::IPERM_ALLOWED && !addons_manager->anyAddonsInstalled()) { new MessageDialog(_("You can not download addons without internet access. " "If you want to download addons, go to options, select " " tab 'User Interface', and edit " "\"Allow STK to connect to the Internet\".")); return; } StateManager::get()->pushScreen(AddonsScreen::getInstance()); } } // eventCallback
/** Called when OK or OK-and-save is clicked. * This will trigger the actual login (if requested) etc. * \param remember_me True if the login details should be remembered, * so that next time this menu can be skipped. */ void BaseUserScreen::login() { // If an error occurs, the callback informing this screen about the // problem will activate the widget again. m_options_widget->setActive(false); m_state = STATE_NONE; PlayerProfile *player = getSelectedPlayer(); PlayerProfile *current = PlayerManager::getCurrentPlayer(); core::stringw new_username = m_username_tb->getText(); // If a different player is connecting, or the same local player with // a different online account, log out the current player. if(current && current->isLoggedIn() && (player!=current || current->getLastOnlineName(true/*ignoreRTL*/)!=new_username) ) { m_sign_out_name = current->getLastOnlineName(true/*ignoreRTL*/); current->requestSignOut(); m_state = (UserScreenState)(m_state | STATE_LOGOUT); // If the online user name was changed, reset the save data // for this user (otherwise later the saved session will be // resumed, not logging the user with the new account). if(player==current && current->getLastOnlineName(true/*ignoreRTL*/)!=new_username) current->clearSession(); } PlayerManager::get()->setCurrentPlayer(player); assert(player); // If no online login requested, log the player out (if necessary) // and go to the main menu screen (though logout needs to finish first) if(!m_online_cb->getState()) { if(player->isLoggedIn()) { m_sign_out_name =player->getLastOnlineName(true/*ignoreRTL*/); player->requestSignOut(); m_state =(UserScreenState)(m_state| STATE_LOGOUT); } player->setWasOnlineLastTime(false); if(m_state==STATE_NONE) { closeScreen(); } return; } // Player wants to be online, and is already online - nothing to do if(player->isLoggedIn()) { player->setWasOnlineLastTime(true); closeScreen(); return; } m_state = (UserScreenState) (m_state | STATE_LOGIN); // Now we need to start a login request to the server // This implies that this screen will wait till the server responds, so // that error messages ('invalid password') can be shown, and the user // can decide what to do about them. if (player->hasSavedSession()) { m_sign_in_name = player->getLastOnlineName(true/*ignoreRTL*/); // Online login with saved token player->requestSavedSession(); } else { // Online login with password --> we need a valid password if (m_password_tb->getText() == "") { m_info_widget->setText(_("You need to enter a password."), true); SFXManager::get()->quickSound("anvil"); m_options_widget->setActive(true); return; } m_sign_in_name = m_username_tb->getText(); player->requestSignIn(m_username_tb->getText(), m_password_tb->getText()); } // !hasSavedSession } // login