1) Synchronised herrings.
2) Fixed no-network play. 3) Fixed display of 'loading'/'synchronising' message. 4) Added missing files from previous commit. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2243 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -40,6 +40,8 @@ supertuxkart_SOURCES = main.cpp \
|
||||
network/connect_message.hpp network/character_info_message.hpp \
|
||||
network/kart_update_message.hpp network/kart_update_message.cpp \
|
||||
network/kart_control_message.hpp network/kart_control_message.cpp \
|
||||
network/flyable_info.hpp network/herring_info.hpp \
|
||||
network/race_state.hpp network/race_state.cpp \
|
||||
utils/random_genertaor.hpp utils/random_generator.cpp \
|
||||
material_manager.cpp material_manager.hpp \
|
||||
grand_prix_manager.cpp grand_prix_manager.hpp \
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "network/flyable_info.hpp"
|
||||
#include "flyable.hpp"
|
||||
#include "world.hpp"
|
||||
#include "kart.hpp"
|
||||
|
||||
@@ -25,23 +25,11 @@
|
||||
#include "kart.hpp"
|
||||
#include "terrain_info.hpp"
|
||||
|
||||
class FlyableInfo;
|
||||
|
||||
class Flyable : public Moveable, public TerrainInfo
|
||||
{
|
||||
public:
|
||||
/** FlyableInfo stores information for updating flyables on the clients.
|
||||
* It contains only the coordinates, rotation, and explosion state. */
|
||||
// -----------------------------------------------------------------------
|
||||
class FlyableInfo
|
||||
{
|
||||
public:
|
||||
Vec3 m_xyz;
|
||||
btQuaternion m_rotation;
|
||||
bool m_exploded;
|
||||
FlyableInfo(const Vec3& xyz, const btQuaternion &rotation, bool exploded) :
|
||||
m_xyz(xyz), m_rotation(rotation), m_exploded(exploded)
|
||||
{};
|
||||
FlyableInfo() {};
|
||||
};
|
||||
private:
|
||||
bool m_has_hit_something;
|
||||
bool m_exploded;
|
||||
|
||||
@@ -56,7 +56,12 @@ CharSel::CharSel(int whichPlayer)
|
||||
{
|
||||
// First time this is called --> switch client and server
|
||||
// to character barrier mode
|
||||
if(network_manager->getState()==NetworkManager::NS_NONE)
|
||||
// FIXME: switchTo ... must be called to clean the kart_info
|
||||
// in the server (even when NW_NONE). This if condition
|
||||
// needs to be checked (otherwise ghost karts and
|
||||
// a ghost camera will appear)
|
||||
if(network_manager->getState()==NetworkManager::NS_NONE ||
|
||||
network_manager->getMode()==NetworkManager::NW_NONE)
|
||||
network_manager->switchToCharacterSelection();
|
||||
|
||||
// For some strange reasons plib calls makeCurrent() in ssgContext
|
||||
|
||||
@@ -30,16 +30,19 @@ enum WidgetTokens
|
||||
|
||||
StartRaceFeedback::StartRaceFeedback()
|
||||
{
|
||||
m_is_first_frame = true;
|
||||
//Add some feedback so people know they are going to start the race
|
||||
widget_manager->reset();
|
||||
widget_manager->addTextWgt( WTOK_MSG, 60, 7, "" );
|
||||
m_loading_text = _("Loading race...");
|
||||
m_synchronising_text = _("Synchronising network...");
|
||||
|
||||
widget_manager->setWgtText(WTOK_MSG, _("Synchronising network..."));
|
||||
|
||||
if(network_manager->getMode()==NetworkManager::NW_NONE)
|
||||
widget_manager->setWgtText(WTOK_MSG, m_loading_text);
|
||||
else // networking
|
||||
// the state and mode are checked in update()
|
||||
widget_manager->setWgtText(WTOK_MSG, m_synchronising_text);
|
||||
{
|
||||
// This copies the local player information to the global
|
||||
// player information in the race manager.
|
||||
network_manager->setupPlayerKartInfo();
|
||||
}
|
||||
|
||||
widget_manager->layout(WGT_AREA_ALL);
|
||||
}
|
||||
@@ -54,6 +57,8 @@ StartRaceFeedback::~StartRaceFeedback()
|
||||
//-----------------------------------------------------------------------------
|
||||
void StartRaceFeedback::update(float delta)
|
||||
{
|
||||
// First test if we are still waiting
|
||||
// ===================================
|
||||
|
||||
// If the server hasn't received all client information, keep on waiting
|
||||
if(network_manager->getMode()==NetworkManager::NW_SERVER &&
|
||||
@@ -70,27 +75,24 @@ void StartRaceFeedback::update(float delta)
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else if(network_manager->getMode()==NetworkManager::NW_CLIENT)
|
||||
{
|
||||
// Client received race information
|
||||
widget_manager->setWgtText(WTOK_MSG, m_loading_text);
|
||||
}
|
||||
|
||||
// Waiting is finished, switch to loading
|
||||
// ======================================
|
||||
widget_manager->setWgtText(WTOK_MSG, _("Loading race..."));
|
||||
widget_manager->update(delta);
|
||||
|
||||
// Pops this menu
|
||||
race_manager->startNew();
|
||||
// We can't do the actual loading etc. in the first call here, since then
|
||||
// the text 'loading' would not be displayed. So a simple state variable
|
||||
// 'is_first_frame' is used to make sure that the text is displayed
|
||||
// before initiating the loading of the race.
|
||||
if(!m_is_first_frame)
|
||||
{
|
||||
if(network_manager->getMode()==NetworkManager::NW_SERVER)
|
||||
{
|
||||
network_manager->sendRaceInformationToClients();
|
||||
}
|
||||
race_manager->startNew();
|
||||
}
|
||||
m_is_first_frame = false;
|
||||
|
||||
} // update
|
||||
|
||||
|
||||
@@ -22,10 +22,8 @@
|
||||
|
||||
class StartRaceFeedback: public BaseGUI
|
||||
{
|
||||
private:
|
||||
char *m_loading_text; // Used to have the actual text in only
|
||||
char *m_synchronising_text; // one place (easier to change, avoids
|
||||
// multiple translations in case of typos)
|
||||
protected:
|
||||
bool m_is_first_frame;
|
||||
public:
|
||||
StartRaceFeedback();
|
||||
~StartRaceFeedback();
|
||||
|
||||
@@ -1616,6 +1616,14 @@
|
||||
RelativePath="..\..\network\connect_message.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\network\flyable_info.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\network\herring_info.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\network\kart_control_message.hpp"
|
||||
>
|
||||
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
unsigned int m_pos; // simple stack counter for constructing packet data
|
||||
bool m_needs_destroy; // only received messages need to be destroyed
|
||||
|
||||
protected:
|
||||
public:
|
||||
void addInt(int data);
|
||||
void addShort(short data);
|
||||
void addString(const std::string &data);
|
||||
@@ -107,18 +107,18 @@ protected:
|
||||
q.setZ(getFloat());
|
||||
q.setW(getFloat());
|
||||
return q; }
|
||||
int getIntLength() const { return sizeof(int); }
|
||||
int getUIntLength() const { return sizeof(int); }
|
||||
int getShortLength() const { return sizeof(short); }
|
||||
int getCharLength() const { return sizeof(char); }
|
||||
int getFloatLength() { return sizeof(float); }
|
||||
int getStringLength(const std::string& s) { return s.size()+1; }
|
||||
int getVec3Length() { return 3*sizeof(float); }
|
||||
int getQuaternionLength() { return 4*sizeof(float); }
|
||||
|
||||
int getStringVectorLength(const std::vector<std::string>& vs);
|
||||
static int getIntLength() { return sizeof(int); }
|
||||
static int getUIntLength() { return sizeof(int); }
|
||||
static int getShortLength() { return sizeof(short); }
|
||||
static int getCharLength() { return sizeof(char); }
|
||||
static int getBoolLength() { return sizeof(char); }
|
||||
static int getFloatLength() { return sizeof(float); }
|
||||
static int getStringLength(const std::string& s) { return s.size()+1;}
|
||||
static int getVec3Length() { return 3*sizeof(float); }
|
||||
static int getQuaternionLength() { return 4*sizeof(float); }
|
||||
static int getStringVectorLength(const std::vector<std::string>& vs);
|
||||
#ifndef WIN32
|
||||
int getSizeTLength(size_t n) { return sizeof(int); }
|
||||
static int getSizeTLength(size_t n) { return sizeof(int); }
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
@@ -343,16 +343,21 @@ void NetworkManager::switchToCharacterSelection()
|
||||
// Change state to wait for list of characters from server
|
||||
m_state = NS_WAIT_FOR_AVAILABLE_CHARACTERS;
|
||||
}
|
||||
else if(m_mode==NW_SERVER)
|
||||
{ // server: create message with all valid characters
|
||||
// ================================================
|
||||
for(unsigned int i=1; i<=m_num_clients; i++)
|
||||
else // Server or no network
|
||||
{
|
||||
if(m_mode==NW_SERVER)
|
||||
{
|
||||
CharacterInfoMessage m(i);
|
||||
enet_peer_send(m_clients[i], 0, m.getPacket());
|
||||
// server: create message with all valid characters
|
||||
// ================================================
|
||||
for(unsigned int i=1; i<=m_num_clients; i++)
|
||||
{
|
||||
CharacterInfoMessage m(i);
|
||||
enet_peer_send(m_clients[i], 0, m.getPacket());
|
||||
}
|
||||
enet_host_flush(m_host);
|
||||
}
|
||||
enet_host_flush(m_host);
|
||||
|
||||
// For server and no network:
|
||||
// ==========================
|
||||
// Prepare the data structures to receive and
|
||||
// store information from all clients.
|
||||
m_num_local_players.clear();
|
||||
|
||||
181
src/network/race_state.cpp
Normal file
181
src/network/race_state.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
// $Id: race_state.cpp 2128 2008-06-13 00:53:52Z cosmosninja $
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
//
|
||||
// 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 "world.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/race_state.hpp"
|
||||
#include "projectile_manager.hpp"
|
||||
|
||||
RaceState *race_state=NULL;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void RaceState::serialise()
|
||||
{
|
||||
// First compute the overall size needed
|
||||
// =====================================
|
||||
int len = 0;
|
||||
|
||||
// 1. Add all kart information
|
||||
// ---------------------------
|
||||
unsigned int num_karts = world->getCurrentNumKarts();
|
||||
KartControl c;
|
||||
// Send the number of karts and for each kart the compressed
|
||||
// control structure, xyz,hpr, and speed (which is necessary to
|
||||
// display the speed, and e.g. to determine when a parachute is detached)
|
||||
len += 1 + num_karts*(KartControl::getCompressedSize()
|
||||
+ getVec3Length()+getQuaternionLength()
|
||||
+ getFloatLength()) ;
|
||||
|
||||
// 2. Add information about eaten herrings
|
||||
// ---------------------------------------
|
||||
|
||||
// We can't use sizeof() here, since the data structures might be padded
|
||||
len += 1 + m_herring_info.size()* HerringInfo::getLength();
|
||||
|
||||
// 3. Add the data about new flyables
|
||||
// ----------------------------------
|
||||
len += 1 + m_new_flyable.size() * 2;
|
||||
|
||||
if(projectile_manager->getNumProjectiles()>0)
|
||||
printf("rocket\n");
|
||||
// 4. Add rocket positions
|
||||
// -----------------------
|
||||
len += 2+projectile_manager->getNumProjectiles()*FlyableInfo::getLength();
|
||||
|
||||
// Now add the data
|
||||
// ================
|
||||
allocate(len);
|
||||
|
||||
// 1. Kart positions
|
||||
// -----------------
|
||||
addChar(num_karts);
|
||||
assert(KartControl::getCompressedSize()<=9);
|
||||
for(unsigned int i=0; i<num_karts; i++)
|
||||
{
|
||||
const Kart* kart=world->getKart(i);
|
||||
const KartControl& kc=kart->getControls();
|
||||
char compressed[9]; // avoid the new/delete overhead
|
||||
kc.compress(compressed);
|
||||
addCharArray(compressed, KartControl::getCompressedSize());
|
||||
addVec3(kart->getXYZ());
|
||||
addQuaternion(kart->getRotation());
|
||||
addFloat(kart->getSpeed());
|
||||
} // for i
|
||||
|
||||
// 2. Eaten herrings
|
||||
// -----------------
|
||||
addChar(m_herring_info.size());
|
||||
for(unsigned int i=0; i<m_herring_info.size(); i++)
|
||||
{
|
||||
m_herring_info[i].serialise(this);
|
||||
}
|
||||
|
||||
// 3. New projectiles
|
||||
// ------------------
|
||||
addChar(m_new_flyable.size());
|
||||
for(unsigned int i=0; i<m_new_flyable.size(); i++)
|
||||
{
|
||||
addChar(m_new_flyable[i].m_type);
|
||||
addChar(m_new_flyable[i].m_kart_id);
|
||||
}
|
||||
|
||||
// 4. Projectiles
|
||||
// --------------
|
||||
addShort(m_flyable_info.size());
|
||||
// The exploded flag could be compressed by combining 8 bits into one byte
|
||||
for(unsigned int i=0; i<m_flyable_info.size(); i++)
|
||||
{
|
||||
m_flyable_info[i].serialise(this);
|
||||
}
|
||||
|
||||
} // serialise
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void RaceState::clear()
|
||||
{
|
||||
m_herring_info.clear();
|
||||
m_flyable_info.clear();
|
||||
} // clear
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Unserialises a race state message.
|
||||
* This function unserialises the message, and updates the state of the race
|
||||
* simulation appropriately.
|
||||
*/
|
||||
void RaceState::receive(ENetPacket *pkt)
|
||||
{
|
||||
Message::receive(pkt, MT_RACE_STATE);
|
||||
|
||||
// 1. Kart information
|
||||
// -------------------
|
||||
unsigned int num_karts = getChar();
|
||||
for(unsigned int i=0; i<num_karts; i++)
|
||||
{
|
||||
assert(KartControl::getCompressedSize()<=9);
|
||||
char compressed[9]; // avoid new/delete overhead
|
||||
getCharArray(compressed, KartControl::getCompressedSize());
|
||||
KartControl kc;
|
||||
kc.uncompress(compressed);
|
||||
// Currently not used!
|
||||
Vec3 xyz = getVec3();
|
||||
btQuaternion q = getQuaternion();
|
||||
Kart *kart = world->getKart(i);
|
||||
kart->setXYZ(xyz);
|
||||
kart->setRotation(q);
|
||||
kart->setSpeed(getFloat());
|
||||
} // for i
|
||||
|
||||
// Eaten herrings
|
||||
// --------------
|
||||
unsigned short num_herrings=getChar();
|
||||
for(unsigned int i=0; i<num_herrings; i++)
|
||||
{
|
||||
HerringInfo hi(this);
|
||||
if(hi.m_herring_id==-1) // Rescue triggered
|
||||
world->getKart(hi.m_kart_id)->forceRescue();
|
||||
else
|
||||
herring_manager->eatenHerring(hi.m_herring_id,
|
||||
world->getKart(hi.m_kart_id),
|
||||
hi.m_add_info);
|
||||
}
|
||||
// 3. New flyables
|
||||
// ---------------
|
||||
unsigned int new_fl = getChar();
|
||||
for(unsigned int i=0; i<new_fl; i++)
|
||||
{
|
||||
char type = getChar();
|
||||
char world_kart_id = getChar();
|
||||
projectile_manager->newProjectile(world->getKart(world_kart_id),
|
||||
(CollectableType)type);
|
||||
}
|
||||
|
||||
// 4. Projectiles
|
||||
// --------------
|
||||
unsigned short num_flyables = getShort();
|
||||
m_flyable_info.clear();
|
||||
m_flyable_info.resize(num_flyables);
|
||||
for(unsigned short i=0; i<projectile_manager->getNumProjectiles(); i++)
|
||||
{
|
||||
FlyableInfo f(this);
|
||||
m_flyable_info[i] = f;
|
||||
}
|
||||
clear(); // free message bugger
|
||||
|
||||
} // receive
|
||||
// ----------------------------------------------------------------------------
|
||||
80
src/network/race_state.hpp
Normal file
80
src/network/race_state.hpp
Normal file
@@ -0,0 +1,80 @@
|
||||
// $Id: race_state.hpp 2128 2008-06-13 00:53:52Z cosmosninja $
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
//
|
||||
// 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 HEADER_RACE_STATE_H
|
||||
#define HEADER_RACE_STATE_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "network/message.hpp"
|
||||
#include "network/herring_info.hpp"
|
||||
#include "network/flyable_info.hpp"
|
||||
#include "herring.hpp"
|
||||
#include "flyable.hpp"
|
||||
|
||||
/** This class stores the state information of a (single) race, e.g. the
|
||||
position and orientation of karts, collisions that have happened etc.
|
||||
It is used for the network version to update the clients with the
|
||||
'official' state information from the server.
|
||||
*/
|
||||
class RaceState : public Message
|
||||
{
|
||||
private:
|
||||
|
||||
/** Updates about collected herrings. */
|
||||
std::vector<HerringInfo> m_herring_info;
|
||||
/** Updates about existing flyables. */
|
||||
std::vector<FlyableInfo> m_flyable_info;
|
||||
/** List of new flyables. */
|
||||
struct NewFlyable{
|
||||
char m_type;
|
||||
char m_kart_id;
|
||||
};
|
||||
std::vector<NewFlyable> m_new_flyable;
|
||||
|
||||
public:
|
||||
RaceState() : Message(MT_RACE_STATE) {}
|
||||
void herringCollected(int kartid, int herring_id, char add_info=-1)
|
||||
{
|
||||
m_herring_info.push_back(HerringInfo(kartid, herring_id, add_info));
|
||||
}
|
||||
void setNumFlyables(int n) { m_flyable_info.resize(n); }
|
||||
void setFlyableInfo(int n, const FlyableInfo& fi)
|
||||
{
|
||||
m_flyable_info[n] = fi;
|
||||
}
|
||||
void newFlyable(char type, char kartid)
|
||||
{
|
||||
NewFlyable nf;
|
||||
nf.m_type = type;
|
||||
nf.m_kart_id = kartid;
|
||||
m_new_flyable.push_back(nf);
|
||||
}
|
||||
void serialise();
|
||||
void receive(ENetPacket *pkt);
|
||||
void clear(); // Removes all currently stored information
|
||||
unsigned int getNumFlyables() const {return m_flyable_info.size(); }
|
||||
const FlyableInfo
|
||||
&getFlyable(unsigned int i) const {return m_flyable_info[i];}
|
||||
}; // RaceState
|
||||
|
||||
extern RaceState *race_state;
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user