Move voting to server lobby

This commit is contained in:
Benau 2018-03-16 14:36:11 +08:00
parent d6936c5746
commit a5c1dbb446
9 changed files with 161 additions and 635 deletions

View File

@ -18,8 +18,8 @@
#include "network/game_setup.hpp"
#include "config/player_manager.hpp"
#include "karts/abstract_kart.hpp"
#include "network/race_config.hpp"
#include "modes/world.hpp"
#include "network/network_player_profile.hpp"
#include "online/online_profile.hpp"
@ -27,23 +27,14 @@
#include "utils/log.hpp"
//-----------------------------------------------------------------------------
GameSetup::GameSetup()
{
m_race_config = new RaceConfig();
m_num_local_players = 0;
m_local_master = 0;
m_laps = 0;
m_reverse = false;
} // GameSetup
//-----------------------------------------------------------------------------
GameSetup::~GameSetup()
{
// remove all players
m_players.clear();
delete m_race_config;
} // ~GameSetup
//-----------------------------------------------------------------------------
void GameSetup::addPlayer(std::shared_ptr<NetworkPlayerProfile> profile)
{
@ -95,7 +86,16 @@ bool GameSetup::isLocalMaster(uint8_t player_id)
} // isLocalMaster
//-----------------------------------------------------------------------------
void GameSetup::loadWorld()
{
assert(!m_track.empty());
// Disable accidentally unlocking of a challenge
PlayerManager::getCurrentPlayer()->setCurrentChallenge("");
race_manager->setReverseTrack(m_reverse);
race_manager->startSingleRace(m_track, m_laps, false/*from_overworld*/);
} // loadWorld
//-----------------------------------------------------------------------------
void GameSetup::bindKartsToProfiles()
{
World::KartList karts = World::getWorld()->getKarts();

View File

@ -31,7 +31,6 @@
#include <vector>
class NetworkPlayerProfile;
class RaceConfig;
// ============================================================================
/*! \class GameSetup
@ -46,9 +45,6 @@ private:
/** Information about all connected players. */
std::vector<std::weak_ptr<NetworkPlayerProfile> > m_players;
/** The race configuration. */
RaceConfig* m_race_config;
/** Stores the number of local players. */
int m_num_local_players;
@ -56,11 +52,17 @@ private:
* kart selection screen. */
uint8_t m_local_master;
std::string m_track;
unsigned m_laps;
bool m_reverse;
public:
// ------------------------------------------------------------------------
GameSetup();
// ------------------------------------------------------------------------
~GameSetup();
~GameSetup() {}
// ------------------------------------------------------------------------
void addPlayer(std::shared_ptr<NetworkPlayerProfile> profile);
// ------------------------------------------------------------------------
@ -78,9 +80,6 @@ public:
/** Returns the nunber of local players. */
int getNumLocalPlayers() const { return m_num_local_players; }
// ------------------------------------------------------------------------
/** Returns the configuration for this race. */
RaceConfig* getRaceConfig() { return m_race_config; }
// ------------------------------------------------------------------------
/** \brief Get the players that are in the game
* \return A vector containing pointers on the players profiles. */
std::vector<std::weak_ptr<NetworkPlayerProfile> > getPlayers() const
@ -98,6 +97,15 @@ public:
// ------------------------------------------------------------------------
/** Returns the id of the local master. */
int getLocalMasterID() const { return m_local_master; }
// ------------------------------------------------------------------------
void setRace(const std::string& track, unsigned laps, bool reverse)
{
m_track = track;
m_laps = laps;
m_reverse = reverse;
}
// ------------------------------------------------------------------------
void loadWorld();
};
#endif // GAME_SETUP_HPP

View File

@ -30,7 +30,6 @@
#include "network/network_player_profile.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/latency_protocol.hpp"
#include "network/race_config.hpp"
#include "network/race_event_manager.hpp"
#include "network/stk_host.hpp"
#include "network/stk_peer.hpp"

View File

@ -28,7 +28,6 @@
#include "network/protocols/game_protocol.hpp"
#include "network/protocols/game_events_protocol.hpp"
#include "network/protocols/latency_protocol.hpp"
#include "network/race_config.hpp"
#include "network/race_event_manager.hpp"
#include "network/rewind_manager.hpp"
#include "race/race_manager.hpp"
@ -74,6 +73,27 @@ void LobbyProtocol::loadWorld()
race_manager->setNumPlayers(m_game_setup->getPlayerCount(),
m_game_setup->getNumLocalPlayers());
// Make sure that if there is only a single local player this player can
// use all input devices.
StateManager::ActivePlayer *ap = race_manager->getNumLocalPlayers()>1
? NULL
: StateManager::get()->getActivePlayer(0);
input_manager->getDeviceManager()->setSinglePlayer(ap);
Log::info("LobbyProtocol", "Player configuration ready.");
// Load the actual world.
m_game_setup->loadWorld();
World::getWorld()->setNetworkWorld(true);
GameProtocol::createInstance()->requestStart();
std::make_shared<GameEventsProtocol>()->requestStart();
} // loadWorld
// ----------------------------------------------------------------------------
void LobbyProtocol::configRemoteKart()
{
// Create the kart information for the race manager:
// -------------------------------------------------
/*std::vector<NetworkPlayerProfile*> players = m_game_setup->getPlayers();
@ -114,24 +134,7 @@ void LobbyProtocol::loadWorld()
// Inform the race manager about the data for this kart.
race_manager->setPlayerKart(i, rki);
} // for i in players*/
// Make sure that if there is only a single local player this player can
// use all input devices.
StateManager::ActivePlayer *ap = race_manager->getNumLocalPlayers()>1
? NULL
: StateManager::get()->getActivePlayer(0);
input_manager->getDeviceManager()->setSinglePlayer(ap);
Log::info("LobbyProtocol", "Player configuration ready.");
// Load the actual world.
m_game_setup->getRaceConfig()->loadWorld();
World::getWorld()->setNetworkWorld(true);
GameProtocol::createInstance()->requestStart();
std::make_shared<GameEventsProtocol>()->requestStart();
} // loadWorld
} // configRemoteKart
// ----------------------------------------------------------------------------
/** Terminates the LatencyProtocol.

View File

@ -23,6 +23,7 @@
#include "network/network_string.hpp"
class GameSetup;
class NetworkPlayerProfile;
/*!
* \class LobbyProtocol
@ -74,6 +75,8 @@ protected:
/** Stores data about the online game to play. */
GameSetup* m_game_setup;
void configRemoteKart();
public:
/** Creates either a client or server lobby protocol as a singleton. */

View File

@ -28,7 +28,6 @@
#include "network/protocols/connect_to_peer.hpp"
#include "network/protocols/latency_protocol.hpp"
#include "network/protocol_manager.hpp"
#include "network/race_config.hpp"
#include "network/race_event_manager.hpp"
#include "network/stk_host.hpp"
#include "network/stk_peer.hpp"
@ -124,6 +123,7 @@ void ServerLobby::setup()
// the server are ready:
m_server_has_loaded_world.store(false);
m_peers_ready.clear();
m_peers_votes.clear();
m_server_delay = 0.0;
Log::info("ServerLobby", "Reset server to initial state.");
} // setup
@ -995,22 +995,117 @@ void ServerLobby::playerVote(Event* event)
event->getPeer()->getPlayerProfiles().empty())
return;
NetworkString& data = event->data();
NetworkString other = NetworkString(PROTOCOL_LOBBY_ROOM);
other.addUInt8(LE_VOTE).encodeString(event->getPeer()
->getPlayerProfiles()[0]->getName());
other += data;
// Check if first vote, if so start counter (10 seconds voting time)
if (m_timeout == std::numeric_limits<float>::max())
m_timeout = (float)StkTime::getRealTime() + 10.0f;
float remaining_time = m_timeout - (float)StkTime::getRealTime();
if (remaining_time < 0.0f)
remaining_time = 0.0f;
{
// Start world
handleVote();
configRemoteKart();
// Reset for next state usage
for (auto p : m_peers_ready)
{
p.second = false;
}
m_state = LOAD_WORLD;
return;
}
NetworkString& data = event->data();
NetworkString other = NetworkString(PROTOCOL_LOBBY_ROOM);
other.addUInt8(LE_VOTE).encodeString(event->getPeer()
->getPlayerProfiles()[0]->getName());
other += data;
std::string track_name;
data.decodeString(&track_name);
m_peers_votes.emplace(event->getPeerSP(), std::forward_as_tuple(track_name,
data.getUInt8(), (bool)data.getUInt8()));
other.addUInt8((uint8_t)remaining_time);
sendMessageToPeersChangingToken(&other);
} // playerVote
// ----------------------------------------------------------------------------
void ServerLobby::handleVote()
{
// Default settings if no votes at all
RandomGenerator rg;
std::set<std::string>::iterator it = m_available_kts.second.begin();
std::advance(it, rg.get((int)m_available_kts.second.size()));
std::string final_track = *it;
unsigned final_laps = UserConfigParams::m_num_laps;
bool final_reverse = (bool)(final_track.size() % 2);
std::map<std::string, unsigned> tracks;
std::map<unsigned, unsigned> laps;
std::map<bool, unsigned> reverses;
for (auto p : m_peers_votes)
{
if (p.first.expired())
continue;
auto track_vote = tracks.find(std::get<0>(p.second));
if (track_vote == tracks.end())
tracks[std::get<0>(p.second)] = 1;
else
track_vote->second++;
auto lap_vote = laps.find(std::get<1>(p.second));
if (lap_vote == laps.end())
laps[std::get<1>(p.second)] = 1;
else
lap_vote->second++;
auto reverse_vote = reverses.find(std::get<2>(p.second));
if (reverse_vote == reverses.end())
reverses[std::get<2>(p.second)] = 1;
else
reverse_vote->second++;
}
unsigned vote = 0;
auto track_vote = tracks.begin();
for (auto c_vote = tracks.begin(); c_vote != tracks.end(); c_vote++)
{
if (c_vote->second > vote)
{
vote = c_vote->second;
track_vote = c_vote;
}
}
if (track_vote != tracks.end())
final_track = track_vote->first;
vote = 0;
auto lap_vote = laps.begin();
for (auto c_vote = laps.begin(); c_vote != laps.end(); c_vote++)
{
if (c_vote->second > vote)
{
vote = c_vote->second;
lap_vote = c_vote;
}
}
if (lap_vote != laps.end())
final_laps = lap_vote->first;
vote = 0;
auto reverse_vote = reverses.begin();
for (auto c_vote = reverses.begin(); c_vote != reverses.end(); c_vote++)
{
if (c_vote->second > vote)
{
vote = c_vote->second;
reverse_vote = c_vote;
}
}
if (reverse_vote != reverses.end())
final_reverse = reverse_vote->first;
m_game_setup->setRace(final_track, final_laps, final_reverse);
} // handleVote
// ----------------------------------------------------------------------------
/** Called from the RaceManager of the server when the world is loaded. Marks
* the server to be ready to start the race.

View File

@ -9,6 +9,7 @@
#include <memory>
#include <mutex>
#include <set>
#include <tuple>
class STKPeer;
@ -49,6 +50,10 @@ private:
std::map<std::weak_ptr<STKPeer>, bool,
std::owner_less<std::weak_ptr<STKPeer> > > m_peers_ready;
/** Vote from each peer. */
std::map<std::weak_ptr<STKPeer>, std::tuple<std::string, uint8_t, bool>,
std::owner_less<std::weak_ptr<STKPeer> > > m_peers_votes;
/** Keeps track of an artificial server delay (which makes sure that the
* data from all clients has arrived when the server computes a certain
* timestep.(. It stores the real time since epoch + delta (atm 0.1
@ -88,6 +93,7 @@ private:
void updatePlayerList();
void updateServerOwner();
bool checkPeersReady() const;
void handleVote();
public:
ServerLobby();

View File

@ -1,452 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "network/race_config.hpp"
#include "config/user_config.hpp"
#include "network/network_config.hpp"
#include "race/race_manager.hpp"
#include "utils/log.hpp"
#include <stdexcept>
/** \brief Gets the element with the highest count in a std::map<S,int>.
* \param histogram : A pointer to the histogram.
* \return The key of type S that has the highest second value.
*/
template<typename S>
S getHighestInHistogram(std::map<S,int>* histogram, S default_value)
{
if(histogram->empty())
return default_value;
S best_item = histogram->begin()->first;
uint8_t highest_count = histogram->begin()->second;
for (typename std::map<S, int>::iterator it = histogram->begin();
it != histogram->end(); it++)
{
if (it->second > highest_count)
{
highest_count = it->second;
best_item = it->first;
}
}
return best_item;
} // getHighestInHistogram
//-----------------------------------------------------------------------------
//--------------------------------- TrackVote --------------------------------
//-----------------------------------------------------------------------------
/** Constructor for a track vote.
*/
TrackVote::TrackVote()
{
has_voted_laps = false;
has_voted_track = false;
has_voted_reversed = false;
} // TrackVote
//-----------------------------------------------------------------------------
/** Sets that this vote is for the specified track.
*/
void TrackVote::voteTrack(const std::string &track)
{
track_info.track = track;
has_voted_track = true;
} // voteTrack
//-----------------------------------------------------------------------------
/** Sets if this vote is for normal or reversed driving.
* \param reversed True if this vote is for reversed racing.
*/
void TrackVote::voteReversed(bool reversed)
{
track_info.reversed = reversed;
has_voted_reversed = true;
} // voteReversed
//-----------------------------------------------------------------------------
/** Votes for the number of laps.
* \param laps Numger of laps.
*/
void TrackVote::voteLaps(uint8_t laps)
{
track_info.laps = laps;
has_voted_laps = true;
} // voteLaps
//-----------------------------------------------------------------------------
//--------------------------------- RaceVote ---------------------------------
//-----------------------------------------------------------------------------
/** Constructor for a race vote.
*/
RaceVote::RaceVote()
{
m_has_voted_major = false;
m_has_voted_minor = false;
m_has_voted_races_count = false;
m_major_mode = 0;
m_minor_mode = 0;
m_races_count = 0;
m_tracks_vote.resize(1);
} // RaceVote
//-----------------------------------------------------------------------------
/** Sets the selected major race vote.
*/
void RaceVote::voteMajor(uint32_t major)
{
m_has_voted_major = true;
m_major_mode = major;
} // voteMajor
//-----------------------------------------------------------------------------
/** Sets the vote for race count.
*/
void RaceVote::voteRaceCount(uint8_t count)
{
m_has_voted_races_count = true;
m_races_count = count;
} // voteRaceCount
//-----------------------------------------------------------------------------
/** Sets vote for minor race mode.
*/
void RaceVote::voteMinor(uint32_t minor)
{
m_has_voted_minor = true;
m_minor_mode = minor;
} // voteMinor
//-----------------------------------------------------------------------------
/** Sets a track vote.
* \param track Name of the track.
*/
void RaceVote::voteTrack(const std::string &track, uint8_t track_number)
{
m_tracks_vote[track_number].voteTrack(track);
} // voteTrack
//-----------------------------------------------------------------------------
/** Sets a vote for reveresed racing.
*/
void RaceVote::voteReversed(bool reversed, uint8_t track_number)
{
m_tracks_vote[track_number].voteReversed(reversed);
} // voteReversed
//-----------------------------------------------------------------------------
/** Sets a vote for number of laps.
*/
void RaceVote::voteLaps(uint8_t laps, uint8_t track_number)
{
m_tracks_vote[track_number].voteLaps(laps);
} // voteLaps
//-----------------------------------------------------------------------------
bool RaceVote::hasVotedMajor() const
{
return m_has_voted_major;
} // hasVotedMajor
//-----------------------------------------------------------------------------
bool RaceVote::hasVotedRacesCount() const
{
return m_has_voted_races_count;
} // hasVotedRacesCount
//-----------------------------------------------------------------------------
bool RaceVote::hasVotedMinor() const
{
return m_has_voted_minor;
} // hasVotedMinor
//-----------------------------------------------------------------------------
bool RaceVote::hasVotedTrack(uint8_t track_number) const
{
return m_tracks_vote[track_number].has_voted_track;
} // hasVotedTrack
//-----------------------------------------------------------------------------
bool RaceVote::hasVotedReversed(uint8_t track_number) const
{
return m_tracks_vote[track_number].has_voted_reversed;
} // hasVotedReversed
//-----------------------------------------------------------------------------
bool RaceVote::hasVotedLaps(uint8_t track_number) const
{
return m_tracks_vote[track_number].has_voted_laps;
} // hasVotedLaps
//-----------------------------------------------------------------------------
uint8_t RaceVote::getMajorVote() const
{
return m_major_mode;
} // getMajorVote
//-----------------------------------------------------------------------------
uint8_t RaceVote::getRacesCountVote() const
{
return m_races_count;
} // getRacesCountVote
//-----------------------------------------------------------------------------
uint8_t RaceVote::getMinorVote() const
{
return m_minor_mode;
} // getMinorVote
//-----------------------------------------------------------------------------
const std::string &RaceVote::getTrackVote(uint8_t track_number) const
{
return m_tracks_vote[track_number].track_info.track;
} // getTrackVote
//-----------------------------------------------------------------------------
bool RaceVote::getReversedVote(uint8_t track_number) const
{
return m_tracks_vote[track_number].track_info.reversed;
} // getReversedVote
//-----------------------------------------------------------------------------
uint8_t RaceVote::getLapsVote(uint8_t track_number) const
{
return m_tracks_vote[track_number].track_info.laps;
} // getLapsVote
//-----------------------------------------------------------------------------
//--------------------------------- RaceConfig -------------------------------
//-----------------------------------------------------------------------------
RaceConfig::RaceConfig()
{
m_max_players = NetworkConfig::get()->getMaxPlayers();
} // RaceConfig
//-----------------------------------------------------------------------------
void RaceConfig::setPlayerMajorVote(uint8_t player_id, uint32_t major)
{
Log::info("RaceConfig", "Player %d voted for major %d", player_id, major);
m_votes[player_id].voteMajor(major);
} // setPlayerMajorVote
//-----------------------------------------------------------------------------
void RaceConfig::setPlayerRaceCountVote(uint8_t player_id, uint8_t count)
{
Log::info("RaceConfig", "Player %d voted for %d races in GP",
player_id, count);
m_votes[player_id].voteRaceCount(count);
} // setPlayerRaceCountVote
//-----------------------------------------------------------------------------
void RaceConfig::setPlayerMinorVote(uint8_t player_id, uint32_t minor)
{
Log::info("RaceConfig", "Player %d voted for minor %d", player_id, minor);
m_votes[player_id].voteMinor(minor);
} // setPlayerMinorVote
//-----------------------------------------------------------------------------
void RaceConfig::setPlayerTrackVote(uint8_t player_id,
const std::string &track, uint8_t track_nb)
{
Log::info("RaceConfig", "Player %d voted for track %s",
player_id, track.c_str());
m_votes[player_id].voteTrack(track, track_nb);
} // setPlayerTrackVote
//-----------------------------------------------------------------------------
void RaceConfig::setPlayerReversedVote(uint8_t player_id, bool reversed,
uint8_t track_nb)
{
if (reversed)
Log::info("RaceConfig", "Player %d voted map %d to be reversed",
player_id, track_nb);
else
Log::info("RaceConfig", "Player %d voted map %d NOT to be reversed",
player_id, track_nb);
m_votes[player_id].voteReversed(reversed, track_nb);
} // setPlayerReversedVote
//-----------------------------------------------------------------------------
void RaceConfig::setPlayerLapsVote(uint8_t player_id, uint8_t lap_count,
uint8_t track_nb)
{
Log::info("RaceConfig", "Player %d voted map %d to have %d laps",
player_id, track_nb, lap_count);
m_votes[player_id].voteLaps(lap_count, track_nb);
} // setPlayerLapsVote
//-----------------------------------------------------------------------------
/** Computes the selected race mode.
*/
void RaceConfig::computeRaceMode()
{
// calculate the race type and number of tracks (in GP mode).
std::map<int,int> major_histogram;
std::map<int,int> races_count_histogram;
std::map<int,int> minor_histogram;
for (unsigned int i = 0; i < m_max_players; i++)
{
// increase the count of votes
if (m_votes[i].hasVotedMajor())
{
try
{
major_histogram.at(m_votes[i].getMajorVote()) ++;
}
catch (const std::out_of_range&) // doesn't exist in the map
{
major_histogram[m_votes[i].getMajorVote()] = 1;
}
}
else if (m_votes[i].hasVotedRacesCount())
{
try
{
races_count_histogram.at(m_votes[i].getRacesCountVote()) ++;
}
catch (const std::out_of_range&) // doesn't exist in the map
{
races_count_histogram[m_votes[i].getRacesCountVote()] = 1;
}
}
else if (m_votes[i].hasVotedMinor())
{
try
{
minor_histogram.at(m_votes[i].getMinorVote()) ++;
}
catch (const std::out_of_range&) // doesn't exist in the map
{
minor_histogram[m_votes[i].getMinorVote()] = 1;
}
}
}
// now we know :
m_major_mode = getHighestInHistogram(&major_histogram,
(int)RaceManager::MAJOR_MODE_SINGLE);
m_minor_mode = getHighestInHistogram(&minor_histogram,
(int)RaceManager::MINOR_MODE_NORMAL_RACE);
if (m_major_mode == RaceManager::MAJOR_MODE_GRAND_PRIX)
{
m_races_count = getHighestInHistogram(&races_count_histogram, 1);
m_tracks.resize(m_races_count);
}
else
{
m_tracks.resize(1);
m_races_count = 1;
}
Log::info("RaceConfig", "Major mode will be %d with %d races. Minor is %d",
m_major_mode, m_races_count, m_minor_mode);
} // computeRaceMode
// ----------------------------------------------------------------------------
void RaceConfig::computeNextTrack()
{
for (unsigned int j = 0; j < m_races_count; j++)
{
// first create histograms of the votes
std::map<std::string,int> tracks_histogram;
std::map<bool,int> reversed_histogram;
std::map<int,int> laps_histogram;
for (unsigned int i = 0; i < m_max_players; i++)
{
// increase the count of votes
if (m_votes[i].hasVotedTrack())
{
try // maps
{
tracks_histogram.at(m_votes[i].getTrackVote()) ++;
}
catch (const std::out_of_range&) // doesn't exist in the map
{
tracks_histogram[m_votes[i].getTrackVote()] = 1;
}
}
if (m_votes[i].hasVotedReversed())
{
try // reversed
{
reversed_histogram.at(m_votes[i].getReversedVote()) ++;
}
catch (const std::out_of_range&) // doesn't exist in the map
{
reversed_histogram[m_votes[i].getReversedVote()] = 1;
}
}
if (m_votes[i].hasVotedLaps())
{
try // laps
{
laps_histogram.at(m_votes[i].getLapsVote()) ++;
}
catch (const std::out_of_range&) // doesn't exist in the mapt
{
laps_histogram[m_votes[i].getLapsVote()] = 1;
}
}
}
// now find the highest votes
m_tracks[j].track = getHighestInHistogram<std::string>(&tracks_histogram,
UserConfigParams::m_last_track);
m_tracks[j].reversed = getHighestInHistogram(&reversed_histogram, false);
m_tracks[j].laps = getHighestInHistogram<int>(&laps_histogram,
UserConfigParams::m_num_laps);
if (m_tracks[j].reversed)
Log::info("RaceConfig",
"Race %d will be on %s with %d laps and reversed",
j, m_tracks[j].track.c_str(), m_tracks[j].laps);
else
Log::info("RaceConfig", "Race %d will be on %s with %d laps",
j, m_tracks[j].track.c_str(), m_tracks[j].laps);
}
} // computeNextTrack
//-----------------------------------------------------------------------------
/** Computes the selected setting (based on the users' vote) and sets them
* in the race manager. Then it loads the world.
*/
void RaceConfig::loadWorld()
{
computeRaceMode();
computeNextTrack();
race_manager->startSingleRace(m_tracks[0].track, m_tracks[0].laps,
m_tracks[0].reversed);
} // loadWorld
//-----------------------------------------------------------------------------
const TrackInfo* RaceConfig::getNextTrackInfo() const
{
return &m_tracks[0];
} // getNextTrackInfo
//-----------------------------------------------------------------------------
int RaceConfig::getNumTrackVotes() const
{
int count = 0;
for (auto entry : m_votes)
{
if (entry.second.hasVotedTrack())
count++;
}
return count;
} // getNumTrackVotes

View File

@ -1,136 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef RACE_CONFIG_HPP
#define RACE_CONFIG_HPP
#include <string>
#include <vector>
#include <map>
#include "utils/types.hpp"
/** Stores the name of a track, number of laps, and reverse driving.
*/
class TrackInfo
{
public:
std::string track;
bool reversed;
uint8_t laps;
TrackInfo() { laps = 0; reversed = false; }
}; // TrackInfo
// ============================================================================
/** Stores a vote about the name of a track, number of laps, and reverse
* driving.
*/
class TrackVote
{
public:
TrackVote();
void voteTrack(const std::string &track);
void voteReversed(bool reversed);
void voteLaps(uint8_t laps);
TrackInfo track_info;
bool has_voted_track;
bool has_voted_reversed;
bool has_voted_laps;
}; // class TrackVote
// ============================================================================
class RaceVote
{
public:
RaceVote();
void voteMajor(uint32_t major);
void voteRaceCount(uint8_t count);
void voteMinor(uint32_t minor);
void voteTrack(const std::string &track, uint8_t track_number = 0);
void voteReversed(bool reversed, uint8_t track_number = 0);
void voteLaps(uint8_t laps, uint8_t track_number = 0);
bool hasVotedMajor() const;
bool hasVotedRacesCount() const;
bool hasVotedMinor() const;
bool hasVotedTrack(uint8_t track_number = 0) const;
bool hasVotedReversed(uint8_t track_number = 0) const;
bool hasVotedLaps(uint8_t track_number = 0) const;
uint8_t getMajorVote() const;
uint8_t getRacesCountVote() const;
uint8_t getMinorVote() const;
const std::string &getTrackVote(uint8_t track_number = 0) const;
bool getReversedVote(uint8_t track_number = 0) const;
uint8_t getLapsVote(uint8_t track_number = 0) const;
private:
uint32_t m_major_mode;
uint32_t m_minor_mode;
uint8_t m_races_count; //!< Stores the number of races that will be in a GP
bool m_has_voted_major;
bool m_has_voted_minor;
bool m_has_voted_races_count;
std::vector<TrackVote> m_tracks_vote;
}; // RaceVote
// ============================================================================
class RaceConfig
{
private:
void computeRaceMode();
void computeNextTrack();
public:
RaceConfig();
void setPlayerMajorVote(uint8_t player_id, uint32_t major);
void setPlayerRaceCountVote(uint8_t player_id, uint8_t count);
void setPlayerMinorVote(uint8_t player_id, uint32_t minor);
void setPlayerTrackVote(uint8_t player_id, const std::string &track,
uint8_t track_nb = 0);
void setPlayerReversedVote(uint8_t player_id, bool reversed,
uint8_t track_nb = 0);
void setPlayerLapsVote(uint8_t player_id, uint8_t lap_count,
uint8_t track_nb = 0);
void loadWorld();
const TrackInfo* getNextTrackInfo() const;
bool getReverse() const;
bool getLapCount() const;
int getNumTrackVotes() const;
const RaceVote& getRaceVote(int global_player_id) { return m_votes[global_player_id]; }
int getMaxPlayers() const { return m_max_players; }
protected:
std::vector<TrackInfo> m_tracks;
int m_minor_mode;
int m_major_mode;
unsigned int m_races_count;
/** Key: globalPlayerID */
std::map<int, RaceVote> m_votes;
uint8_t m_max_players;
}; // class RaceConfig
#endif // RACE_CONFIG_HPP