1) Synchronised random-karts across the network.

2) Fixed non-network game play.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2239 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2008-09-07 14:24:40 +00:00
parent db75ee21f0
commit 545a2703b5
8 changed files with 94 additions and 57 deletions

View File

@@ -155,7 +155,10 @@ CharSel::CharSel(int whichPlayer)
}
}
else
{
widget_manager->hideWgt(WTOK_MESSAGE);
updateScrollPosition();
}
m_clock = 0;

View File

@@ -70,7 +70,13 @@ void StartRaceFeedback::update(float delta)
return;
}
if(network_manager->getMode()==NetworkManager::NW_SERVER)
if(network_manager->getMode()==NetworkManager::NW_NONE)
{
// This copies the loca lplayer information to the global
// player information in the race manager
network_manager->setupPlayerKartInfo();
}
else if(network_manager->getMode()==NetworkManager::NW_SERVER)
{
network_manager->sendRaceInformationToClients();
widget_manager->setWgtText(WTOK_MSG, m_loading_text);

View File

@@ -183,22 +183,22 @@ bool KartPropertiesManager::kartAvailable(int kartid)
} // testAndSetKart
//-----------------------------------------------------------------------------
void KartPropertiesManager::fillWithRandomKarts(std::vector<RemoteKartInfo>& vec)
std::vector<std::string> KartPropertiesManager::getRandomKartList(int count,
RemoteKartInfoList& existing_karts)
{
std::vector<std::string> random_karts;
// First: set up flags (based on global kart
// index) for which karts are already used
// -----------------------------------------
std::vector<bool> used;
used.resize(getNumberOfKarts(), false);
int count=vec.size();
std::vector<std::string> all_karts;
for(unsigned int i=0; i<vec.size(); i++)
for(unsigned int i=0; i<existing_karts.size(); i++)
{
if(vec[i].getKartName()=="") continue;
int id=getKartId(vec[i].getKartName());
int id=getKartId(existing_karts[i].getKartName());
used[id] = true;
count --;
}
// Add karts from the current group
@@ -218,17 +218,14 @@ void KartPropertiesManager::fillWithRandomKarts(std::vector<RemoteKartInfo>& vec
// Loop over all karts to fill till either all slots are filled, or
// there are no more karts in the current group
for(unsigned int i=0; i<vec.size() && count>0 && karts.size()>0; i++)
while(count>0 && karts.size()>0)
{
if(vec[i].getKartName()=="")
{
used[karts.back()] = true;
vec[i] = RemoteKartInfo(m_karts_properties[karts.back()]->getIdent());
karts.pop_back();
count --;
}
used[karts.back()] = true;
random_karts.push_back(m_karts_properties[karts.back()]->getIdent());
karts.pop_back();
count --;
}
if(count==0) return;
if(count==0) return random_karts;
// Not enough karts in chosen group, so fill the rest with arbitrary karts
// -----------------------------------------------------------------------
@@ -240,17 +237,15 @@ void KartPropertiesManager::fillWithRandomKarts(std::vector<RemoteKartInfo>& vec
}
std::random_shuffle(karts.begin(), karts.end());
// Then fill up the remaining empty spaces
for(unsigned int i=0; i<vec.size() && count>0 && karts.size()>0; i++)
while(count>0 && karts.size()>0)
{
if(vec[i].getKartName()=="")
{
vec[i] = RemoteKartInfo(m_karts_properties[karts.back()]->getIdent());
karts.pop_back();
count --;
}
random_karts.push_back(m_karts_properties[karts.back()]->getIdent());
karts.pop_back();
count --;
}
// There should never be more karts to be selected than there are.
// There should always be enough karts
assert(count==0);
} // fillWithRandomKarts
return random_karts;
} // getRandomKartList
/* EOF */

View File

@@ -62,8 +62,8 @@ public:
int getNumSelectedKarts() const {return m_selected_karts.size();}
bool kartAvailable(int kartid);
bool testAndSetKart(int kartid);
/** Fill the empty positions in the given vector with random karts */
void fillWithRandomKarts (std::vector<RemoteKartInfo>& vec);
std::vector<std::string>
getRandomKartList(int count, RemoteKartInfoList& existing_karts);
void removeTextures ();
};

View File

@@ -73,7 +73,7 @@ void Message::allocate(int size)
// ----------------------------------------------------------------------------
bool Message::add(int data)
{
if (m_pos > m_data_size)
if ((int)(m_pos + sizeof(int)) > m_data_size)
return false;
int l=htonl(data);
memcpy(m_data+m_pos, &l, sizeof(int));
@@ -88,13 +88,6 @@ int Message::getInt()
return ntohl(*(int*)(&m_data[m_pos-sizeof(int)]));
} // getInt
// ----------------------------------------------------------------------------
bool Message::add(float data)
{
int *dcast = (int*) &data;
return add(*dcast);
} // add<float>
// ----------------------------------------------------------------------------
float Message::getFloat()
{ // ugly...
@@ -107,7 +100,7 @@ float Message::getFloat()
bool Message::add(const std::string &data)
{
int len = data.size()+1; // copy 0 end byte
assert(m_pos+len <=m_data_size);
assert((int)(m_pos+len) <=m_data_size);
memcpy (&(m_data[m_pos]), data.c_str(), len);
m_pos += len;
return true;
@@ -122,3 +115,31 @@ std::string Message::getString()
return std::string(str);
} // getString
// ----------------------------------------------------------------------------
int Message::getLength(const std::vector<std::string>& vs)
{
int len=getLength(vs.size());
for(unsigned int i=0; i<vs.size(); i++)
len += getLength(vs[i]);
return len;
} // getLength(vector<string>)
// ----------------------------------------------------------------------------
bool Message::add(const std::vector<std::string>& vs)
{
bool result = add(vs.size());
if(!result) return false;
for(unsigned int i=0; i<vs.size(); i++)
if(!add(vs[i])) return false;
return true;
} // add(vector<string>)
// ----------------------------------------------------------------------------
std::vector<std::string> Message::getStringVector()
{
std::vector<std::string> vs;
vs.resize(getInt());
for(unsigned int i=0; i<vs.size(); i++)
vs[i]=getString();
return vs;
} // getStringVector
// ----------------------------------------------------------------------------

View File

@@ -58,4 +58,6 @@ public:
}
}; // RemoteKartInfo
typedef std::vector<RemoteKartInfo> RemoteKartInfoList;
#endif

View File

@@ -116,6 +116,14 @@ void RaceManager::setTrack(const std::string& track)
m_tracks.push_back(track);
} // setTrack
//-----------------------------------------------------------------------------
void RaceManager::computeRandomKartList()
{
m_random_kart_list=kart_properties_manager->getRandomKartList(m_num_karts - m_player_karts.size(),
m_player_karts);
} // computeRandomKartList
//-----------------------------------------------------------------------------
void RaceManager::startNew()
{
@@ -131,30 +139,27 @@ void RaceManager::startNew()
if((size_t)m_num_karts < m_player_karts.size())
m_num_karts = (int)m_player_karts.size();
// Create the list of all kart names to use
// ========================================
std::vector<std::string> kart_names;
kart_names.resize(m_num_karts);
for(unsigned int i = 0; i < m_player_karts.size(); i++)
{
/*Players position is behind the AI in the first race*/
kart_names[m_num_karts-1 - i] = m_player_karts[m_player_karts.size() - 1 - i];
}
kart_properties_manager->fillWithRandomKarts(kart_names);
// Create the kart status data structure to keep track of scores, times, ...
// ==========================================================================
const int num_ai_karts = m_num_karts - (int)m_player_karts.size();
m_kart_status.clear();
for(int i=0; i<m_num_karts; i++)
// First add the AI karts (randomly chosen)
// ----------------------------------------
for(unsigned int i=0; i<m_random_kart_list.size(); i++)
m_kart_status.push_back(KartStatus(m_random_kart_list[i], i, -1, -1, KT_AI));
// Then the players, which start behind the AI karts
// -------------------------------------------------
for(int i=m_player_karts.size()-1; i>=0; i--)
{
// AI karts have -1 as player
bool is_player = i>=num_ai_karts; // players start at the back
m_kart_status.push_back(KartStatus(kart_names[i], i,
is_player ? i-num_ai_karts : -1,
is_player ? KT_PLAYER: KT_AI
KartType kt=(m_player_karts[i].getHostId()==network_manager->getMyHostId())
? KT_PLAYER : KT_NETWORK_PLAYER;
m_kart_status.push_back(KartStatus(m_player_karts[i].getKartName(), i,
m_player_karts[i].getLocalPlayerId(),
m_player_karts[i].getGlobalPlayerId(),
kt
) );
} // for i<m_num_karts
}
// Then start the race with the first track
// ========================================

View File

@@ -86,6 +86,7 @@ private:
std::vector<int> m_host_ids;
std::vector<int> m_num_laps;
std::vector<int> m_score_for_position;
std::vector<std::string> m_random_kart_list;
int m_track_number;
GrandPrixData m_grand_prix;
int m_num_karts;
@@ -152,11 +153,15 @@ public:
int getPositionScore(int p) const { return m_score_for_position[p-1]; }
int allPlayerFinished() const {return
m_num_finished_players==m_player_karts.size();}
int raceIsActive() const { return m_active_race; }
int raceIsActive() const { return m_active_race; }
const std::vector<std::string>&
getRandomKartList() const { return m_random_kart_list; }
void setRandomKartList(const std::vector<std::string>& rkl)
{ m_random_kart_list = rkl; }
void computeRandomKartList();
void setMirror() {/*FIXME*/}
void setReverse(){/*FIXME*/}
void startNew(); // start new race/GP/...
void next(); // start the next race or go back to the start screen
void rerunRace(); // Rerun the same race again