diff --git a/data/gui/screens/tracks.stkgui b/data/gui/screens/tracks.stkgui
old mode 100644
new mode 100755
index 968d54281..d114380e0
--- a/data/gui/screens/tracks.stkgui
+++ b/data/gui/screens/tracks.stkgui
@@ -23,7 +23,6 @@
wrap_around="true" />
-
diff --git a/sources.cmake b/sources.cmake
index 3e53f13e9..ba4868d71 100644
--- a/sources.cmake
+++ b/sources.cmake
@@ -1,5 +1,5 @@
# Modify this file to change the last-modified date when you add/remove a file.
-# This will then trigger a new cmake run automatically.
+# This will then trigger a new cmake run automatically.
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
diff --git a/src/main_loop.cpp b/src/main_loop.cpp
index 92898ab7b..00a2635d7 100644
--- a/src/main_loop.cpp
+++ b/src/main_loop.cpp
@@ -42,7 +42,7 @@
#include "race/history.hpp"
#include "race/race_manager.hpp"
#include "states_screens/state_manager.hpp"
-#include "states_screens/online/vote_overview.hpp"
+#include "states_screens/online/tracks_screen.hpp"
#include "utils/profiler.hpp"
#include "utils/time.hpp"
@@ -568,7 +568,7 @@ void MainLoop::renderGUI(int phase, int loop_index, int loop_size)
if (NetworkConfig::get()->isNetworking() && phase >= 5000)
{
- VoteOverview::getInstance()->showVoteResult();
+ TracksScreen::getInstance()->showVoteResult();
}
// TODO: remove debug output
//Log::verbose("mainloop", "Rendergui t %llu dt %f phase %d index %d / %d",
diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp
index f6d1ff653..908d66eb9 100644
--- a/src/network/protocols/client_lobby.cpp
+++ b/src/network/protocols/client_lobby.cpp
@@ -44,7 +44,6 @@
#include "network/stk_peer.hpp"
#include "states_screens/online/networking_lobby.hpp"
#include "states_screens/online/network_kart_selection.hpp"
-#include "states_screens/online/vote_overview.hpp"
#include "states_screens/race_result_gui.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/online/tracks_screen.hpp"
@@ -122,7 +121,7 @@ void ClientLobby::setup()
{
clearPlayers();
m_received_server_result = false;
- VoteOverview::getInstance()->resetVote();
+ TracksScreen::getInstance()->resetVote();
LobbyProtocol::setup();
m_state.store(NONE);
} // setup
@@ -244,7 +243,7 @@ void ClientLobby::addAllPlayers(Event* event)
PeerVote winner_vote(data);
m_game_setup->setRace(winner_vote);
- VoteOverview::getInstance()->setResult(winner_vote);
+ TracksScreen::getInstance()->setResult(winner_vote);
std::shared_ptr peer = event->getPeerSP();
peer->cleanPlayerProfiles();
@@ -465,8 +464,8 @@ void ClientLobby::receivePlayerVote(Event* event)
if (!track)
Log::fatal("ClientLobby", "Missing track %s", vote.m_track_name.c_str());
- VoteOverview *overview = VoteOverview::getInstance();
- overview->addVote(host_id2);
+ TracksScreen *ts = TracksScreen::getInstance();
+ ts->addVote(host_id2);
} // receivePlayerVote
@@ -678,7 +677,7 @@ void ClientLobby::updatePlayerList(Event* event)
m_total_players = total_players;
NetworkingLobby::getInstance()->updatePlayers(players);
- VoteOverview::getInstance()->updateNumPlayers(players.size());
+ TracksScreen::getInstance()->updateNumPlayers(players.size());
} // updatePlayerList
//-----------------------------------------------------------------------------
@@ -858,8 +857,8 @@ void ClientLobby::startSelection(Event* event)
screen->push();
}
- VoteOverview *overview = VoteOverview::getInstance();
- overview->resetVote();
+ TracksScreen *ts = TracksScreen::getInstance();
+ ts->resetVote();
m_state.store(SELECTING_ASSETS);
Log::info("ClientLobby", "Selection starts now");
} // startSelection
diff --git a/src/states_screens/online/tracks_screen.cpp b/src/states_screens/online/tracks_screen.cpp
index ff71c9181..55f75b8cf 100644
--- a/src/states_screens/online/tracks_screen.cpp
+++ b/src/states_screens/online/tracks_screen.cpp
@@ -35,7 +35,6 @@
#include "network/protocols/client_lobby.hpp"
#include "network/network_config.hpp"
#include "network/stk_host.hpp"
-#include "states_screens/online/vote_overview.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/track_info_screen.hpp"
#include "tracks/track.hpp"
@@ -55,11 +54,12 @@ static const char ALL_TRACK_GROUPS_ID[] = "all";
void TracksScreen::eventCallback(Widget* widget, const std::string& name,
const int playerID)
{
- if (name == "submit")
+ if ((name == "lap-spinner" || name == "reverse") &&
+ STKHost::existHost() && m_selected_track != NULL)
{
voteForPlayer();
- VoteOverview::getInstance()->push();
}
+
else if (name == "tracks")
{
DynamicRibbonWidget* w2 = dynamic_cast(widget);
@@ -90,8 +90,8 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name,
selection = m_random_track_list.front();
m_random_track_list.pop_front();
m_random_track_list.push_back(selection);
-
} // selection=="random_track"
+
m_selected_track = track_manager->getTrack(selection);
if (m_selected_track)
@@ -99,6 +99,7 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name,
if (STKHost::existHost())
{
w2->setBadge(selection, OK_BADGE);
+ voteForPlayer();
}
else
{
@@ -512,3 +513,153 @@ void TracksScreen::onUpdate(float dt)
m_timer->setValue(new_value * 100.0f);
} // onUpdate
+
+// ----------------------------------------------------------------------------
+/** Called when the final 'random picking' animation is finished so that only
+ * the result is shown : all votes except the winner is set to be invisible.
+ */
+void TracksScreen::showVoteResult()
+{
+ Log::info("TracksScreen", "showVoteResult: winning index %d",
+ m_winning_index);
+ // TODO: Make all listed votes except the winner invisible: something
+ // like this:
+ //for (unsigned int i = 0; i < 8; i++)
+ //{
+ // std::string box_name = StringUtils::insertValues("rect-box%d", i);
+ // Widget *box = getWidget(box_name.c_str());
+ // if (i != m_winning_index)
+ // box->setVisible(false);
+ // else
+ // box->setSelected(PLAYER_ID_GAME_MASTER, true);
+ //}
+} // showVoteResult
+
+// ----------------------------------------------------------------------------
+/** Stores the number of players. This can be used to determine how many
+ * slotes for votes are required. This function is called from ClientLobby
+ * upon an update from the server.
+ * \param n New number of players that can vote.
+ */
+void TracksScreen::updateNumPlayers(int n)
+{
+ m_max_num_votes = n;
+} //updateNumPlayers
+
+// -----------------------------------------------------------------------------
+/** Selects in which part of the vote list the new host is being shown and
+ * stores this information in the m_index_to_hostid mapping. If the host_id is
+ * already mapped, this is ignored (this can happen in case one host changes
+ * its vote.
+ * \param host_id Index of the host that is voting.
+ */
+void TracksScreen::addVote(int host_id)
+{
+ auto it = std::find(m_index_to_hostid.begin(), m_index_to_hostid.end(),
+ host_id);
+
+ Log::verbose("TracksScreen", "addVote: hostid %d is new %d",
+ host_id, it == m_index_to_hostid.end());
+
+ // Add a new index if this is the first vote for the host/
+ if (it == m_index_to_hostid.end())
+ {
+ m_index_to_hostid.push_back(host_id);
+ }
+
+ // If the screen is already shown, update the voting display
+ if (GUIEngine::getCurrentScreen() == this)
+ showVote(host_id);
+} // addVote
+
+// ----------------------------------------------------------------------------
+/** Populates one entry in the voting list with the vote from the
+ * corresponding host. A mapping of host_id to index MUST exist for this
+ * host when this function is called.
+ * \param host_id Host id from hich a new vote was received.
+ */
+void TracksScreen::showVote(int host_id)
+{
+ auto it = std::find(m_index_to_hostid.begin(), m_index_to_hostid.end(),
+ host_id);
+ assert(it != m_index_to_hostid.end());
+
+ int index = it - m_index_to_hostid.begin();
+
+ auto lp = LobbyProtocol::get();
+ const PeerVote *vote = lp->getVote(host_id);
+ assert(vote);
+
+ // This is the old code that needs to be updated for the new list display
+#ifdef OLD_DISPLAY
+ std::string s = StringUtils::insertValues("name-%d", index);
+ LabelWidget *name_widget = getWidget(s.c_str());
+ name_widget->setText(_("Name: %s", vote->m_player_name), true);
+
+ s = StringUtils::insertValues("track-%d", index);
+ IconButtonWidget *track_widget = getWidget(s.c_str());
+ Track *track = track_manager->getTrack(vote->m_track_name);
+ track_widget->setVisible(true);
+ track_widget->setImage(track->getScreenshotFile());
+
+ s = StringUtils::insertValues("numlaps-%d", index);
+ LabelWidget *laps_widget = getWidget(s.c_str());
+ laps_widget->setText(_("Laps: %d", vote->m_num_laps), true);
+
+ s = StringUtils::insertValues("reverse-%d", index);
+ LabelWidget *reverse_widget = getWidget(s.c_str());
+ core::stringw yes = _("yes");
+ core::stringw no = _("no");
+ reverse_widget->setText(_("Reverse: %s", vote->m_reverse ? yes : no),
+ true);
+#endif
+} // addVote
+
+// -----------------------------------------------------------------------------
+/** Received the winning vote. i.e. the data about the track to play (including
+ * #laps etc).
+ */
+void TracksScreen::setResult(const PeerVote &winner_vote)
+{
+ // If the GUI is forced from the server lobby, m_timer is not defined
+ if (m_timer) m_timer->setVisible(false);
+
+ // Note that the votes on the server might have a different order from
+ // the votes here on the client. Potentially there could also be a missing
+ // vote(??)
+ auto lp = LobbyProtocol::get();
+ m_winning_index = -1;
+ for (unsigned int i = 0; i < m_index_to_hostid.size(); i++)
+ {
+ const PeerVote *vote = lp->getVote(m_index_to_hostid[i]);
+ if (!vote) continue;
+ if (vote->m_track_name == winner_vote.m_track_name &&
+ vote->m_num_laps == winner_vote.m_num_laps &&
+ vote->m_reverse == winner_vote.m_reverse)
+ {
+ m_winning_index = i;
+ break;
+ }
+ // Try to prepare a fallback in case that the right vote is not here.
+ if (vote->m_track_name == winner_vote.m_track_name)
+ {
+ m_winning_index = i;
+ }
+ } // for i in m_index_to_hostid
+
+ if (m_winning_index == -1)
+ {
+ // We don't have the right vote. Assume that a message got lost,
+ // In this case, change one non-local vote:
+ for (unsigned int i = 0; i < m_index_to_hostid.size(); i++)
+ {
+ if (m_index_to_hostid[i] != STKHost::get()->getMyHostId())
+ {
+ lp->addVote(m_index_to_hostid[i], winner_vote);
+ m_winning_index = i;
+ break;
+ }
+ }
+ } // wim_winning_index == -1
+
+} // setResult
diff --git a/src/states_screens/online/tracks_screen.hpp b/src/states_screens/online/tracks_screen.hpp
index a82b48434..7467223b2 100644
--- a/src/states_screens/online/tracks_screen.hpp
+++ b/src/states_screens/online/tracks_screen.hpp
@@ -20,15 +20,17 @@
#include "guiengine/screen.hpp"
#include "utils/synchronised.hpp"
-#include
-#include
-#include