diff --git a/src/config/user_config.hpp b/src/config/user_config.hpp index 15b379313..dac05cb14 100644 --- a/src/config/user_config.hpp +++ b/src/config/user_config.hpp @@ -586,7 +586,7 @@ namespace UserConfigParams PARAM_DEFAULT(BoolUserConfigParam(false, "hq_mipmap", &m_video_group, "Generate mipmap for textures using " "high quality method with SSE")); - + // ---- Recording PARAM_PREFIX GroupUserConfigParam m_recording_group PARAM_DEFAULT(GroupUserConfigParam("Recording", @@ -780,6 +780,11 @@ namespace UserConfigParams PARAM_PREFIX BoolUserConfigParam m_kick_high_ping_players PARAM_DEFAULT(BoolUserConfigParam(false, "kick-high-ping-players", &m_network_group, "Kick players whose ping is above max-ping.")); + PARAM_PREFIX FloatUserConfigParam m_auto_lap_ratio + PARAM_DEFAULT(FloatUserConfigParam(-1.0f, "auto-lap-ratio", + &m_network_group, "Value used by server to automatically calculate lap of each race in network game, " + "if more than 0.0f, the number of lap of each track vote in linear race will be determined " + "by max(1.0f, auto-lap-ratio * default lap of that track).")); // ---- Gamemode setup PARAM_PREFIX UIntToUIntUserConfigParam m_num_karts_per_gamemode diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index c308989c3..523411bf7 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -72,7 +72,9 @@ engine. ClientLobby::ClientLobby(const TransportAddress& a, std::shared_ptr s) : LobbyProtocol(NULL) { - m_waiting_for_game.store(false); + m_waiting_for_game = false; + m_server_auto_lap = false; + m_received_server_result = false; m_state.store(NONE); m_server_address = a; m_server = s; @@ -628,7 +630,7 @@ void ClientLobby::updatePlayerList(Event* event) if (!checkDataSize(event, 1)) return; NetworkString& data = event->data(); bool waiting = data.getUInt8() == 1; - if (m_waiting_for_game.load() && !waiting) + if (m_waiting_for_game && !waiting) { // The waiting game finished NetworkingLobby::getInstance() @@ -636,7 +638,7 @@ void ClientLobby::updatePlayerList(Event* event) SFXManager::get()->quickSound("wee"); } - m_waiting_for_game.store(waiting); + m_waiting_for_game = waiting; unsigned player_count = data.getUInt8(); std::vector > players; @@ -803,7 +805,8 @@ void ClientLobby::startSelection(Event* event) { SFXManager::get()->quickSound("wee"); const NetworkString& data = event->data(); - uint8_t skip_kart_screen = data.getUInt8(); + bool skip_kart_screen = data.getUInt8() == 1; + m_server_auto_lap = data.getUInt8() == 1; const unsigned kart_num = data.getUInt16(); const unsigned track_num = data.getUInt16(); m_available_karts.clear(); @@ -829,7 +832,7 @@ void ClientLobby::startSelection(Event* event) screen->setAvailableKartsFromServer(m_available_karts); // In case of auto-connect or continue a grand prix, use random karts // (or previous kart) from server and go to track selection - if (NetworkConfig::get()->isAutoConnect() || skip_kart_screen == 1) + if (NetworkConfig::get()->isAutoConnect() || skip_kart_screen) { input_manager->setMasterPlayerOnly(true); for (auto& p : NetworkConfig::get()->getNetworkPlayers()) diff --git a/src/network/protocols/client_lobby.hpp b/src/network/protocols/client_lobby.hpp index d409513f6..af40c3fcf 100644 --- a/src/network/protocols/client_lobby.hpp +++ b/src/network/protocols/client_lobby.hpp @@ -71,7 +71,11 @@ private: EXITING }; - std::atomic_bool m_waiting_for_game; + bool m_waiting_for_game; + + bool m_server_auto_lap; + + bool m_received_server_result; /** The state of the finite state machine. */ std::atomic m_state; @@ -79,8 +83,6 @@ private: std::set m_available_karts; std::set m_available_tracks; - bool m_received_server_result = false; - void addAllPlayers(Event* event); void finalizeConnectionRequest(NetworkString* header, BareNetworkString* rest, bool encrypt); @@ -108,7 +110,8 @@ public: bool waitingForServerRespond() const { return m_state.load() == REQUESTING_CONNECTION; } bool isLobbyReady() const { return m_state.load() == CONNECTED; } - bool isWaitingForGame() const { return m_waiting_for_game.load(); } + bool isWaitingForGame() const { return m_waiting_for_game; } + bool isServerAutoLap() const { return m_server_auto_lap; } virtual bool isRacing() const OVERRIDE { return m_state.load() == RACING; } }; diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index ba5c9a30f..002defb5d 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -796,7 +796,8 @@ void ServerLobby::startSelection(const Event *event) // a new screen, which must be done from the main thread. ns->setSynchronous(true); ns->addUInt8(LE_START_SELECTION).addUInt8( - m_game_setup->isGrandPrixStarted() ? 1 : 0); + m_game_setup->isGrandPrixStarted() ? 1 : 0) + .addUInt8(UserConfigParams::m_auto_lap_ratio > 0.0f ? 1 : 0); // Remove karts / tracks from server that are not supported on all clients std::set karts_erase, tracks_erase; @@ -1750,18 +1751,41 @@ void ServerLobby::playerVote(Event* event) } NetworkString& data = event->data(); + std::string track_name; + data.decodeString(&track_name); + uint8_t lap = data.getUInt8(); + uint8_t reverse = data.getUInt8(); + + if (race_manager->modeHasLaps()) + { + if (UserConfigParams::m_auto_lap_ratio > 0.0f) + { + Track* t = track_manager->getTrack(track_name); + if (t) + { + lap = (uint8_t)(fmaxf(1.0f, + (float)t->getDefaultNumberOfLaps() * + UserConfigParams::m_auto_lap_ratio)); + } + else + { + // Prevent someone send invalid vote + track_name = *m_available_kts.second.begin(); + lap = (uint8_t)3; + } + } + else if (lap == 0) + lap = (uint8_t)3; + } + NetworkString other = NetworkString(PROTOCOL_LOBBY_ROOM); std::string name = StringUtils::wideToUtf8(event->getPeer() ->getPlayerProfiles()[0]->getName()); other.setSynchronous(true); other.addUInt8(LE_VOTE).addFloat(UserConfigParams::m_voting_timeout) - .encodeString(name).addUInt32(event->getPeer()->getHostId()); - other += data; + .encodeString(name).addUInt32(event->getPeer()->getHostId()) + .encodeString(track_name).addUInt8(lap).addUInt8(reverse); - std::string track_name; - data.decodeString(&track_name); - uint8_t lap = data.getUInt8(); - uint8_t reverse = data.getUInt8(); m_peers_votes[event->getPeerSP()] = std::make_tuple(track_name, lap, reverse == 1); sendMessageToPeers(&other); diff --git a/src/states_screens/tracks_screen.cpp b/src/states_screens/tracks_screen.cpp index 9456eb789..6c3c266af 100644 --- a/src/states_screens/tracks_screen.cpp +++ b/src/states_screens/tracks_screen.cpp @@ -305,13 +305,24 @@ void TracksScreen::init() } else { - getWidget("lap-text")->setVisible(true); - //I18N: In track screen - getWidget("lap-text")->setText(_("Number of laps"), false); - m_laps->setVisible(true); - m_laps->setMin(1); - m_laps->setMax(20); - m_laps->setValue(UserConfigParams::m_num_laps); + auto cl = LobbyProtocol::get(); + assert(cl); + if (cl->isServerAutoLap()) + { + getWidget("lap-text")->setVisible(false); + m_laps->setVisible(false); + m_laps->setValue(0); + } + else + { + getWidget("lap-text")->setVisible(true); + //I18N: In track screen + getWidget("lap-text")->setText(_("Number of laps"), false); + m_laps->setVisible(true); + m_laps->setMin(1); + m_laps->setMax(20); + m_laps->setValue(UserConfigParams::m_num_laps); + } getWidget("reverse-text")->setVisible(true); //I18N: In track screen getWidget("reverse-text")->setText(_("Drive in reverse"), false);