Very first alpha version of network multiplayer.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2240 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
545a2703b5
commit
da69106378
@ -32,12 +32,15 @@ supertuxkart_SOURCES = main.cpp \
|
||||
material.cpp material.hpp \
|
||||
network/network_manager.cpp network/network_manager.hpp \
|
||||
network/network_kart.cpp network/network_kart.hpp \
|
||||
network/message.cpp network/message.hpp \
|
||||
network/race_info_message.hpp network/race_info_message.cpp \
|
||||
network/remote_kart_info.hpp network/character_selected_message.hpp \
|
||||
network/race_start_message.hpp network/connect_message.hpp \
|
||||
network.num_players_message.hpp network/world_loaded_message.hpp \
|
||||
network/connect_message.hpp network/character_info_message.hpp \
|
||||
network/message.cpp network/message.hpp \
|
||||
network/kart_update_message.hpp network/kart_update_message.cpp \
|
||||
network/kart_control_message.hpp network/kart_control_message.cpp \
|
||||
utils/random_genertaor.hpp utils/random_generator.cpp \
|
||||
material_manager.cpp material_manager.hpp \
|
||||
grand_prix_manager.cpp grand_prix_manager.hpp \
|
||||
attachment.cpp attachment.hpp \
|
||||
@ -49,7 +52,7 @@ supertuxkart_SOURCES = main.cpp \
|
||||
music_information.cpp music_information.hpp \
|
||||
sfx_openal.cpp sfx_openal.hpp \
|
||||
smoke.cpp smoke.hpp \
|
||||
input.hpp \
|
||||
input.hpp kart_control.hpp \
|
||||
isect.cpp isect.hpp \
|
||||
track.cpp track.hpp \
|
||||
herring.cpp herring.hpp \
|
||||
|
@ -72,7 +72,7 @@ void Attachment::hitGreenHerring()
|
||||
case ATTACH_BOMB: projectile_manager->newExplosion(m_kart->getXYZ());
|
||||
m_kart->handleExplosion(m_kart->getXYZ(), /*direct_hit*/ true);
|
||||
clear();
|
||||
random_attachment = rand()%3;
|
||||
random_attachment = m_random.get(3);
|
||||
break;
|
||||
case ATTACH_ANVIL :// if the kart already has an anvil, attach a new anvil,
|
||||
// and increase the overall time
|
||||
@ -83,7 +83,7 @@ void Attachment::hitGreenHerring()
|
||||
random_attachment = 2; // anvil
|
||||
leftover_time = m_time_left;
|
||||
break;
|
||||
default: random_attachment = rand()%3;
|
||||
default: random_attachment = m_random.get(3);
|
||||
} // switch
|
||||
|
||||
switch (random_attachment)
|
||||
@ -104,7 +104,7 @@ void Attachment::hitGreenHerring()
|
||||
// handled in Kart::updatePhysics
|
||||
m_kart->adjustSpeedWeight(stk_config->m_anvil_speed_factor);
|
||||
break ;
|
||||
} // switch rand()%3
|
||||
} // switch
|
||||
} // hitGreenHerring
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -21,6 +21,8 @@
|
||||
#define HEADER_ATTACHMENT_H
|
||||
|
||||
#include "stk_config.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
|
||||
class Kart;
|
||||
|
||||
// Some loop in Attachment.cpp depend on PARACHUTE being the first element,
|
||||
@ -42,6 +44,7 @@ private:
|
||||
ssgSelector *m_holder; // where the attachment is put on the kart
|
||||
Kart *m_previous_owner; // used by bombs so that it's not passed
|
||||
// back to previous owner
|
||||
RandomGenerator m_random;
|
||||
public:
|
||||
Attachment(Kart* _kart);
|
||||
~Attachment();
|
||||
|
@ -153,7 +153,7 @@ void Collectable::hitRedHerring(int n)
|
||||
{
|
||||
const int SPECIAL_PROB = (int)(15.0 / ((float)world->getCurrentNumKarts() /
|
||||
(float)m_owner->getPosition()));
|
||||
const int RAND_NUM = rand()%100;
|
||||
const int RAND_NUM = m_random.get(100);
|
||||
if(RAND_NUM <= SPECIAL_PROB)
|
||||
{
|
||||
//If the driver in the first position has finished, give the driver
|
||||
@ -170,7 +170,7 @@ void Collectable::hitRedHerring(int n)
|
||||
}
|
||||
}
|
||||
|
||||
m_type = rand()%(2) == 0 ? COLLECT_ANVIL : COLLECT_PARACHUTE;
|
||||
m_type = m_random.get(2) == 0 ? COLLECT_ANVIL : COLLECT_PARACHUTE;
|
||||
m_number = 1;
|
||||
return;
|
||||
}
|
||||
@ -182,7 +182,7 @@ void Collectable::hitRedHerring(int n)
|
||||
CollectableType newC;
|
||||
if(!user_config->m_profile)
|
||||
{
|
||||
newC = (CollectableType)(rand()%(COLLECT_MAX - 1 - 2) + 1);
|
||||
newC = (CollectableType)(m_random.get(COLLECT_MAX - 1 - 2) + 1);
|
||||
}
|
||||
else
|
||||
{ // for now: no collectables when profiling
|
||||
|
@ -23,11 +23,14 @@
|
||||
#define MAX_COLLECTABLES 5
|
||||
|
||||
#include "collectable_manager.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
|
||||
class Kart;
|
||||
|
||||
class Collectable
|
||||
{
|
||||
private:
|
||||
RandomGenerator m_random;
|
||||
protected:
|
||||
Kart* m_owner;
|
||||
CollectableType m_type;
|
||||
|
@ -105,16 +105,24 @@ void GameManager::run()
|
||||
}
|
||||
|
||||
network_manager->update(dt);
|
||||
|
||||
if (race_manager->raceIsActive())
|
||||
{
|
||||
// Busy wait if race_manager is active (i.e. creating of world is done)
|
||||
// till all clients have reached this state.
|
||||
if(network_manager->getState()==NetworkManager::NS_READY_SET_GO_BARRIER) continue;
|
||||
|
||||
// Server: Send the current position and previous controls to all clients
|
||||
// Client: send current controls to server
|
||||
network_manager->sendUpdates();
|
||||
music_on = false;
|
||||
if(user_config->m_profile) dt=1.0f/60.0f;
|
||||
// In the first call dt might be large (includes loading time),
|
||||
// which can cause the camera to significantly tilt
|
||||
scene->draw(world->getPhase()==World::SETUP_PHASE ? 0.0f : dt);
|
||||
|
||||
network_manager->receiveUpdates();
|
||||
|
||||
if ( world->getPhase() != World::LIMBO_PHASE)
|
||||
{
|
||||
world->update(dt);
|
||||
|
@ -157,7 +157,7 @@ RaceGUI::handle(GameAction ga, int value)
|
||||
int playerNo = ka / KC_COUNT;
|
||||
ka = ka % KC_COUNT;
|
||||
|
||||
world->getPlayerKart(playerNo)->action((KartAction) ka, value);
|
||||
world->getLocalPlayerKart(playerNo)->action((KartAction) ka, value);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -170,7 +170,7 @@ RaceGUI::handle(GameAction ga, int value)
|
||||
case GA_DEBUG_ADD_BOWLING:
|
||||
if (race_manager->getNumPlayers() ==1 )
|
||||
{
|
||||
Kart* kart = world->getPlayerKart(0);
|
||||
Kart* kart = world->getLocalPlayerKart(0);
|
||||
kart->setCollectable(COLLECT_BOWLING, 10000);
|
||||
}
|
||||
break;
|
||||
@ -787,7 +787,7 @@ void RaceGUI::drawLap(Kart* kart, int offset_x, int offset_y,
|
||||
{
|
||||
// Don't display laps in follow the leader mode
|
||||
if(!race_manager->raceHasLaps()) return;
|
||||
|
||||
if(kart->getLap()<0) return; // don't display 'lap 0/...'
|
||||
float maxRatio = std::max(ratio_x, ratio_y);
|
||||
char str[256];
|
||||
offset_x += (int)(120*ratio_x);
|
||||
|
File diff suppressed because it is too large
Load Diff
17
src/kart.hpp
17
src/kart.hpp
@ -26,24 +26,11 @@
|
||||
|
||||
#include "moveable.hpp"
|
||||
#include "kart_properties.hpp"
|
||||
#include "kart_control.hpp"
|
||||
#include "attachment.hpp"
|
||||
#include "collectable.hpp"
|
||||
#include "terrain_info.hpp"
|
||||
|
||||
struct KartControl
|
||||
{
|
||||
float lr;
|
||||
float accel;
|
||||
bool brake;
|
||||
bool wheelie;
|
||||
bool jump;
|
||||
bool rescue;
|
||||
bool fire;
|
||||
|
||||
KartControl() : lr(0.0f), accel(0.0f), brake(false),
|
||||
wheelie(false), jump(false), rescue(false), fire(false){}
|
||||
};
|
||||
|
||||
class SkidMark;
|
||||
class Herring;
|
||||
class Smoke;
|
||||
@ -189,6 +176,8 @@ public:
|
||||
float getWheelieSpeedBoost() const
|
||||
{return m_kart_properties->getWheelieSpeedBoost(); }
|
||||
float getSteerPercent () const {return m_controls.lr; }
|
||||
const KartControl&
|
||||
getControls () const {return m_controls; }
|
||||
float getMaxSpeed () const {return m_max_speed; }
|
||||
void setTimeAtLap (float t){m_time_at_last_lap=t; }
|
||||
float getTimeAtLap () const {return m_time_at_last_lap; }
|
||||
|
@ -24,9 +24,18 @@
|
||||
|
||||
class CharacterInfoMessage : public Message
|
||||
{
|
||||
// For now this is an empty message
|
||||
// Add the remote host id to this message (to avoid sending this separately)
|
||||
public:
|
||||
CharacterInfoMessage() :Message(Message::MT_CHARACTER_INFO) {allocate(0);}
|
||||
CharacterInfoMessage(ENetPacket* pkt):Message(pkt, MT_CHARACTER_INFO) {}
|
||||
CharacterInfoMessage(int hostid) :Message(Message::MT_CHARACTER_INFO)
|
||||
{
|
||||
allocate(getLength(hostid));
|
||||
add(hostid);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
CharacterInfoMessage(ENetPacket* pkt):Message(pkt, MT_CHARACTER_INFO)
|
||||
{
|
||||
int hostid=getInt();
|
||||
network_manager->setHostId(hostid);
|
||||
}
|
||||
}; // CharacterInfoMessage
|
||||
#endif
|
||||
|
57
src/network/kart_control_message.cpp
Normal file
57
src/network/kart_control_message.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
// $Id:kart_control_message.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 "kart_control_message.hpp"
|
||||
#include "world.hpp"
|
||||
#include "network/network_kart.hpp"
|
||||
|
||||
KartControlMessage::KartControlMessage()
|
||||
: Message(Message::MT_KART_CONTROL)
|
||||
{
|
||||
unsigned int num_local_players = world->getCurrentNumLocalPlayers();
|
||||
unsigned int control_size = KartControl::getCompressedSize();
|
||||
assert(control_size<=9);
|
||||
allocate(control_size*num_local_players);
|
||||
for(unsigned int i=0; i<num_local_players; i++)
|
||||
{
|
||||
const Kart *kart = world->getLocalPlayerKart(i);
|
||||
const KartControl& controls = kart->getControls();
|
||||
char c[9];
|
||||
controls.compress(c);
|
||||
add(c, control_size);
|
||||
}
|
||||
} // KartControlMessage
|
||||
// ----------------------------------------------------------------------------
|
||||
// kart_id_offset is the global id of the first kart on the host from which
|
||||
// this packet was received.
|
||||
KartControlMessage::KartControlMessage(ENetPacket* pkt, int kart_id_offset,
|
||||
int num_local_players)
|
||||
: Message(pkt, MT_KART_CONTROL)
|
||||
{
|
||||
assert(KartControl::getCompressedSize()<=9);
|
||||
for(int i=kart_id_offset; i<kart_id_offset+num_local_players; i++)
|
||||
{
|
||||
char c[9];
|
||||
getChar(c, KartControl::getCompressedSize());
|
||||
KartControl kc;
|
||||
kc.uncompress(c);
|
||||
NetworkKart *kart=world->getNetworkKart(i);
|
||||
kart->setControl(kc);
|
||||
}
|
||||
}; // KartControlMessage
|
||||
|
32
src/network/kart_control_message.hpp
Normal file
32
src/network/kart_control_message.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
// $Id:kart_control_message.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_KART_CONTROL_MESSAGE_H
|
||||
#define HEADER_KART_CONTROL_MESSAGE_H
|
||||
|
||||
#include "network/message.hpp"
|
||||
|
||||
class KartControlMessage : public Message
|
||||
{
|
||||
public:
|
||||
KartControlMessage();
|
||||
KartControlMessage(ENetPacket* pkt, int kart_id_offset,
|
||||
int num_local_players);
|
||||
}; // KartUpdateMessage
|
||||
#endif
|
64
src/network/kart_update_message.cpp
Normal file
64
src/network/kart_update_message.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
// $Id:kart_update_message.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 "kart_update_message.hpp"
|
||||
#include "world.hpp"
|
||||
#include "kart.hpp"
|
||||
|
||||
KartUpdateMessage::KartUpdateMessage()
|
||||
: Message(Message::MT_KART_INFO)
|
||||
{
|
||||
unsigned int num_karts = world->getCurrentNumKarts();
|
||||
KartControl c;
|
||||
// Send the number of karts and for each kart the compressed
|
||||
// control structure (3 ints) and xyz,hpr (4 floats: quaternion:
|
||||
allocate(getLength(num_karts)+
|
||||
num_karts*(KartControl::getCompressedSize() + 7*getLength(1.0f)) );
|
||||
add(num_karts);
|
||||
for(unsigned int i=0; i<num_karts; i++)
|
||||
{
|
||||
const Kart* kart=world->getKart(i);
|
||||
const KartControl& kc=kart->getControls();
|
||||
assert(KartControl::getCompressedSize()<=9);
|
||||
char compressed[9]; // avoid the new/delete overhead
|
||||
kc.compress(compressed);
|
||||
add(compressed, KartControl::getCompressedSize());
|
||||
add(kart->getXYZ());
|
||||
add(kart->getRotation());
|
||||
} // for i
|
||||
} // KartUpdateMessage
|
||||
// ----------------------------------------------------------------------------
|
||||
KartUpdateMessage::KartUpdateMessage(ENetPacket* pkt)
|
||||
: Message(pkt, MT_KART_INFO)
|
||||
{
|
||||
unsigned int num_karts = getInt();
|
||||
for(unsigned int i=0; i<num_karts; i++)
|
||||
{
|
||||
assert(KartControl::getCompressedSize()<=9);
|
||||
char compressed[9]; // avoid new/delete overhead
|
||||
getChar(compressed, KartControl::getCompressedSize());
|
||||
KartControl kc;
|
||||
kc.uncompress(compressed);
|
||||
Vec3 xyz = getVec3();
|
||||
btQuaternion q = getQuaternion();
|
||||
Kart *kart = world->getKart(i);
|
||||
kart->setXYZ(xyz);
|
||||
kart->setRotation(q);
|
||||
} // for i
|
||||
}; // KartUpdateMessage
|
||||
|
31
src/network/kart_update_message.hpp
Normal file
31
src/network/kart_update_message.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
// $Id:kart_update_message.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_KART_UPDATE_MESSAGE_H
|
||||
#define HEADER_KART_UPDATE_MESSAGE_H
|
||||
|
||||
#include "network/message.hpp"
|
||||
|
||||
class KartUpdateMessage : public Message
|
||||
{
|
||||
public:
|
||||
KartUpdateMessage();
|
||||
KartUpdateMessage(ENetPacket* pkt);
|
||||
}; // KartUpdateMessage
|
||||
#endif
|
@ -23,11 +23,14 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
|
||||
#ifdef HAVE_ENET
|
||||
# include "enet/enet.h"
|
||||
#endif
|
||||
|
||||
#include "vec3.hpp"
|
||||
|
||||
// sjl: when a message is received, need to work out what kind of message it
|
||||
// is and therefore what to do with it
|
||||
|
||||
@ -36,33 +39,69 @@ class Message
|
||||
{
|
||||
public:
|
||||
enum MessageType {MT_CONNECT=1, MT_CHARACTER_INFO,
|
||||
MT_RACE_INFO, MT_RACE_START, MT_WORLD_LOADED};
|
||||
MT_RACE_INFO, MT_RACE_START, MT_WORLD_LOADED,
|
||||
MT_KART_INFO, MT_KART_CONTROL};
|
||||
private:
|
||||
ENetPacket *m_pkt;
|
||||
char *m_data;
|
||||
MessageType m_type;
|
||||
int m_data_size;
|
||||
int m_pos; // simple stack counter for constructing packet data
|
||||
unsigned int m_pos; // simple stack counter for constructing packet data
|
||||
bool m_needs_destroy; // only received messages need to be destroyed
|
||||
|
||||
protected:
|
||||
bool add(int data);
|
||||
#ifndef WIN32 // on windows size_t is unsigned int
|
||||
bool add(size_t data) { return add((int)data); }
|
||||
#endif
|
||||
bool add(unsigned int data) { return add((int)data); }
|
||||
bool add(float data);
|
||||
bool add(const std::string &data);
|
||||
bool add(const std::vector<std::string>& vs);
|
||||
bool add(float data) { return add(*(int*)&data); }
|
||||
bool add(char *c, unsigned int n)
|
||||
{ if((int)(m_pos+n)>m_data_size)
|
||||
return false;
|
||||
memcpy(m_data+m_pos,c,n);
|
||||
m_pos+=n;
|
||||
return true; }
|
||||
#ifndef WIN32 // on windows size_t is unsigned int
|
||||
bool add(size_t data) { return add((int)data); }
|
||||
#endif
|
||||
bool add(unsigned int data) { return add(*(int*)&data); }
|
||||
bool add(int *d, unsigned int n)
|
||||
{ for(unsigned int i=0;
|
||||
i<n-1; i++)
|
||||
add(d[i]);
|
||||
return add(d[n-1]); }
|
||||
bool add(const Vec3& v) { add(v.getX());
|
||||
add(v.getY());
|
||||
return add(v.getZ()); }
|
||||
bool add(const btQuaternion& q) { add(q.getX());
|
||||
add(q.getY());
|
||||
add(q.getZ());
|
||||
return add(q.getW()); }
|
||||
int getInt();
|
||||
float getFloat();
|
||||
std::string getString();
|
||||
std::vector<std::string>
|
||||
getStringVector();
|
||||
int getLength(int n) { return sizeof(int); }
|
||||
int getLength(unsigned int n) { return sizeof(int); }
|
||||
int getLength(float f) { return sizeof(float); }
|
||||
int getLength(const std::string& s) { return s.size()+1; }
|
||||
void getChar(char *c, int n) {memcpy(c,m_data+m_pos,n);
|
||||
m_pos+=n;
|
||||
return; }
|
||||
Vec3 getVec3() { Vec3 v;
|
||||
v.setX(getFloat());
|
||||
v.setY(getFloat());
|
||||
v.setZ(getFloat());
|
||||
return v; }
|
||||
btQuaternion getQuaternion() { btQuaternion q;
|
||||
q.setX(getFloat());
|
||||
q.setY(getFloat());
|
||||
q.setZ(getFloat());
|
||||
q.setW(getFloat());
|
||||
return q; }
|
||||
int getLength(int n) { return sizeof(int); }
|
||||
int getLength(unsigned int n) { return sizeof(int); }
|
||||
int getLength(float f) { return sizeof(float); }
|
||||
int getLength(const std::string& s) { return s.size()+1; }
|
||||
int getLength(const Vec3& v) { return 3*sizeof(float); }
|
||||
int getLength(const btQuaternion &q){ return 4*sizeof(float); }
|
||||
|
||||
int getLength(const std::vector<std::string>& vs);
|
||||
#ifndef WIN32
|
||||
int getLength(size_t n) { return sizeof(int); }
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "race_info_message.hpp"
|
||||
#include "race_start_message.hpp"
|
||||
#include "world_loaded_message.hpp"
|
||||
#include "kart_update_message.hpp"
|
||||
#include "kart_control_message.hpp"
|
||||
#include "stk_config.hpp"
|
||||
#include "user_config.hpp"
|
||||
#include "race_manager.hpp"
|
||||
@ -206,7 +208,7 @@ void NetworkManager::handleMessageAtServer(ENetEvent *event)
|
||||
case NS_CHARACTER_SELECT:
|
||||
{
|
||||
CharacterSelectedMessage m(event->packet);
|
||||
int hostid=(int)(long)event->peer->data;
|
||||
unsigned int hostid=(unsigned int)(long)event->peer->data;
|
||||
assert(hostid>=1 && hostid<=m_num_clients);
|
||||
if(m_num_local_players[hostid]==-1) // first package from that host
|
||||
{
|
||||
@ -222,7 +224,7 @@ void NetworkManager::handleMessageAtServer(ENetEvent *event)
|
||||
// one message from each client, and the size of the kart_info
|
||||
// array is the same as the number of all players (which does not
|
||||
// yet include the number of players on the host).
|
||||
if(m_barrier_count == m_num_clients &&
|
||||
if(m_barrier_count == (int)m_num_clients &&
|
||||
m_num_all_players==(int)m_kart_info.size())
|
||||
{
|
||||
// we can't send the race info yet, since the server might
|
||||
@ -234,7 +236,7 @@ void NetworkManager::handleMessageAtServer(ENetEvent *event)
|
||||
case NS_READY_SET_GO_BARRIER:
|
||||
{
|
||||
m_barrier_count ++;
|
||||
if(m_barrier_count==m_num_clients)
|
||||
if(m_barrier_count==(int)m_num_clients)
|
||||
{
|
||||
m_state = NS_RACING;
|
||||
RaceStartMessage m;
|
||||
@ -273,7 +275,17 @@ void NetworkManager::handleMessageAtClient(ENetEvent *event)
|
||||
m_state = NS_RACING;
|
||||
break;
|
||||
}
|
||||
default: assert(0); // should not happen
|
||||
case NS_RACING:
|
||||
{
|
||||
KartUpdateMessage k(event->packet);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
printf("received unknown message: type %d\n",
|
||||
Message::peekType(event->packet));
|
||||
// assert(0); // should not happen
|
||||
}
|
||||
} // switch m_state
|
||||
} // handleMessageAtClient
|
||||
|
||||
@ -281,6 +293,10 @@ void NetworkManager::handleMessageAtClient(ENetEvent *event)
|
||||
void NetworkManager::update(float dt)
|
||||
{
|
||||
if(m_mode==NW_NONE) return;
|
||||
// Messages during racing are handled in the sendUpdates/receiveUpdate
|
||||
// calls, so don't do anything in this case.
|
||||
if(m_state==NS_RACING) return;
|
||||
|
||||
ENetEvent event;
|
||||
int result = enet_host_service (m_host, &event, 0);
|
||||
if(result==0) return;
|
||||
@ -311,9 +327,9 @@ void NetworkManager::broadcastToClients(Message &m)
|
||||
} // broadcastToClients
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void NetworkManager::sendToServer(Message* m)
|
||||
void NetworkManager::sendToServer(Message &m)
|
||||
{
|
||||
enet_peer_send(m_server, 0, m->getPacket());
|
||||
enet_peer_send(m_server, 0, m.getPacket());
|
||||
enet_host_flush(m_host);
|
||||
} // sendToServer
|
||||
|
||||
@ -330,8 +346,12 @@ void NetworkManager::switchToCharacterSelection()
|
||||
else if(m_mode==NW_SERVER)
|
||||
{ // server: create message with all valid characters
|
||||
// ================================================
|
||||
CharacterInfoMessage m;
|
||||
broadcastToClients(m);
|
||||
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);
|
||||
|
||||
// Prepare the data structures to receive and
|
||||
// store information from all clients.
|
||||
@ -340,6 +360,7 @@ void NetworkManager::switchToCharacterSelection()
|
||||
// be able to use the hostid as index, we have to allocate one
|
||||
// additional element.
|
||||
m_num_local_players.resize(m_num_clients+1, -1);
|
||||
m_num_local_players[0] = race_manager->getNumLocalPlayers();
|
||||
m_kart_info.clear();
|
||||
m_num_all_players = 0;
|
||||
// use barrier count to see if we had at least one message from each host
|
||||
@ -353,7 +374,7 @@ void NetworkManager::switchToCharacterSelection()
|
||||
void NetworkManager::sendCharacterSelected(int player_id)
|
||||
{
|
||||
CharacterSelectedMessage m(player_id);
|
||||
sendToServer(&m);
|
||||
sendToServer(m);
|
||||
} // sendCharacterSelected
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -368,7 +389,7 @@ void NetworkManager::worldLoaded()
|
||||
if(m_mode==NW_CLIENT)
|
||||
{
|
||||
WorldLoadedMessage m;
|
||||
sendToServer(&m);
|
||||
sendToServer(m);
|
||||
m_state = NS_READY_SET_GO_BARRIER;
|
||||
}
|
||||
} // worldLoaded
|
||||
@ -386,16 +407,21 @@ void NetworkManager::setupPlayerKartInfo()
|
||||
// Now sort by (hostid, playerid)
|
||||
std::sort(m_kart_info.begin(), m_kart_info.end());
|
||||
|
||||
// Set the global player ID for each player
|
||||
for(unsigned int i=0; i<m_kart_info.size(); i++)
|
||||
m_kart_info[i].setGlobalPlayerId(i);
|
||||
|
||||
// Set the player kart information
|
||||
race_manager->setNumPlayers(m_kart_info.size());
|
||||
|
||||
// Set the global player ID for each player
|
||||
for(unsigned int i=0; i<m_kart_info.size(); i++)
|
||||
{
|
||||
m_kart_info[i].setGlobalPlayerId(i);
|
||||
race_manager->setPlayerKart(i, m_kart_info[i]);
|
||||
}
|
||||
// Compute the id of the first kart from each host
|
||||
m_kart_id_offset.resize(m_num_clients+1);
|
||||
m_kart_id_offset[0]=0;
|
||||
for(unsigned int i=1; i<=m_num_clients; i++)
|
||||
m_kart_id_offset[i]=m_kart_id_offset[i-1]+m_num_local_players[i-1];
|
||||
|
||||
race_manager->computeRandomKartList();
|
||||
} // setupPlayerKartInfo
|
||||
|
||||
@ -406,6 +432,7 @@ void NetworkManager::sendRaceInformationToClients()
|
||||
{
|
||||
if(m_mode==NW_SERVER)
|
||||
{
|
||||
setupPlayerKartInfo();
|
||||
RaceInfoMessage m(m_kart_info);
|
||||
broadcastToClients(m);
|
||||
}
|
||||
@ -418,6 +445,96 @@ void NetworkManager::sendRaceInformationToClients()
|
||||
void NetworkManager::sendConnectMessage()
|
||||
{
|
||||
ConnectMessage msg;
|
||||
sendToServer(&msg);
|
||||
sendToServer(msg);
|
||||
} // sendConnectMessage
|
||||
// ----------------------------------------------------------------------------
|
||||
/*** Send all kart controls and kart positions to all clients
|
||||
*/
|
||||
void NetworkManager::sendUpdates()
|
||||
{
|
||||
if(m_mode==NW_SERVER)
|
||||
{
|
||||
KartUpdateMessage m;
|
||||
broadcastToClients(m);
|
||||
}
|
||||
else
|
||||
{
|
||||
KartControlMessage m;
|
||||
sendToServer(m);
|
||||
}
|
||||
} // sendUpdates
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void NetworkManager::receiveUpdates()
|
||||
{
|
||||
// The server receives m_num_clients messages, each client one message
|
||||
int num_messages = m_mode==NW_SERVER ? m_num_clients : 1;
|
||||
ENetEvent event;
|
||||
bool correct=true;
|
||||
|
||||
for(int i=0; i<num_messages; i++)
|
||||
{
|
||||
int result = enet_host_service (m_host, &event, 0);
|
||||
if(result<0)
|
||||
{
|
||||
fprintf(stderr, m_mode==NW_SERVER
|
||||
? "Error while waiting for client control - chaos will reign.\n"
|
||||
: "Error while waiting for server update - chaos will reign.\n");
|
||||
correct=false;
|
||||
continue;
|
||||
}
|
||||
// if no message, busy wait
|
||||
if(result==0 || event.type==ENET_EVENT_TYPE_NONE)
|
||||
{
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
if(event.type!=ENET_EVENT_TYPE_RECEIVE)
|
||||
{
|
||||
fprintf(stderr, "unexpected message, ignored.\n");
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
if(m_mode==NW_SERVER)
|
||||
{
|
||||
int host_id = getHostId(event.peer);
|
||||
KartControlMessage(event.packet, host_id, m_num_local_players[host_id]);
|
||||
}
|
||||
else
|
||||
{
|
||||
KartUpdateMessage(event.packet);
|
||||
}
|
||||
} // for i<num_messages
|
||||
if(!correct)
|
||||
fprintf(stderr, "Missing messages need to be handled!\n");
|
||||
|
||||
} // receiveUpdates
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void NetworkManager::waitForClientData()
|
||||
{
|
||||
ENetEvent event;
|
||||
bool correct=true;
|
||||
for(unsigned int i=1; i<=m_num_clients; i++)
|
||||
{
|
||||
int result = enet_host_service (m_host, &event, 100);
|
||||
if(result<=0)
|
||||
{
|
||||
fprintf(stderr, "Error while waiting for client control - chaos will reign.\n");
|
||||
correct=false;
|
||||
continue;
|
||||
}
|
||||
if(event.type!=ENET_EVENT_TYPE_RECEIVE)
|
||||
{
|
||||
fprintf(stderr, "received no message - chaos will reign.\n");
|
||||
correct=false;
|
||||
continue;
|
||||
}
|
||||
int host_id = getHostId(event.peer);
|
||||
KartControlMessage(event.packet, host_id, m_num_local_players[host_id]);
|
||||
}
|
||||
if(!correct)
|
||||
fprintf(stderr, "Missing messages need to be handled!\n");
|
||||
|
||||
} // waitForClientData
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -51,11 +51,12 @@ private:
|
||||
|
||||
NetworkMode m_mode;
|
||||
NetworkState m_state;
|
||||
int m_num_clients;
|
||||
unsigned int m_num_clients;
|
||||
std::vector<RemoteKartInfo> m_kart_info;
|
||||
int m_host_id;
|
||||
std::vector<std::string> m_client_names;
|
||||
std::vector<int> m_num_local_players;
|
||||
std::vector<int> m_kart_id_offset; // kart id of first kart on host i
|
||||
int m_num_all_players;
|
||||
int m_barrier_count;
|
||||
|
||||
@ -75,9 +76,8 @@ private:
|
||||
// about lost precision, then cast long to int to get the right type
|
||||
unsigned int getHostId(ENetPeer *p) const {return (int)(long)p->data; }
|
||||
|
||||
void sendToServer(Message *m);
|
||||
void sendToServer(Message &m);
|
||||
void broadcastToClients(Message &m);
|
||||
void sendToClient(int id, const Message *m);
|
||||
public:
|
||||
NetworkManager();
|
||||
~NetworkManager();
|
||||
@ -85,12 +85,11 @@ public:
|
||||
NetworkMode getMode() const {return m_mode; }
|
||||
void setState(NetworkState s) {m_state = s; }
|
||||
NetworkState getState() const {return m_state; }
|
||||
int getHostId() const {return m_host_id; }
|
||||
int getMyHostId() const {return m_host_id; }
|
||||
void setHostId(int host_id) {m_host_id = host_id; }
|
||||
unsigned int getNumClients() const {return m_num_clients; }
|
||||
const std::string&
|
||||
getClientName(int i) const {return m_client_names[i];}
|
||||
void setKartInfo(int player_id, const std::string& kart,
|
||||
const std::string& user="", int hostid=-1);
|
||||
bool initialiseConnections();
|
||||
void update(float dt);
|
||||
|
||||
@ -100,13 +99,11 @@ public:
|
||||
void sendCharacterSelected(int player_id);
|
||||
void waitForRaceInformation();
|
||||
void worldLoaded();
|
||||
|
||||
// which one is actually necessary:
|
||||
void setupPlayerKartInfo();
|
||||
void sendRaceInformationToClients();
|
||||
|
||||
void switchToRaceDataSynchronisation();
|
||||
void switchToReadySetGoBarrier();
|
||||
void sendUpdates();
|
||||
void receiveUpdates();
|
||||
void waitForClientData();
|
||||
};
|
||||
|
||||
extern NetworkManager *network_manager;
|
||||
|
@ -48,7 +48,6 @@ void PlayerKart::reset()
|
||||
m_steer_val_l = 0;
|
||||
m_steer_val_r = 0;
|
||||
m_steer_val = 0;
|
||||
m_accel_val = 0;
|
||||
m_controls.accel = 0.0;
|
||||
m_controls.brake =false;
|
||||
m_controls.fire = false;
|
||||
@ -82,11 +81,11 @@ void PlayerKart::action(KartAction action, int value)
|
||||
|
||||
break;
|
||||
case KA_ACCEL:
|
||||
m_accel_val = value;
|
||||
m_controls.accel = value/32768.0f;
|
||||
break;
|
||||
case KA_BRAKE:
|
||||
if (value)
|
||||
m_accel_val = 0;
|
||||
m_controls.accel = 0;
|
||||
m_controls.brake = (value!=0); // This syntax avoid visual c++ warning (when brake=value)
|
||||
break;
|
||||
case KA_WHEELIE:
|
||||
@ -150,8 +149,6 @@ void PlayerKart::update(float dt)
|
||||
{
|
||||
steer(dt, m_steer_val);
|
||||
|
||||
m_controls.accel = m_accel_val / 32768.0f;
|
||||
|
||||
if(world->isStartPhase())
|
||||
{
|
||||
if(m_controls.accel!=0.0 || m_controls.brake!=false ||
|
||||
|
@ -33,7 +33,7 @@ class Camera;
|
||||
class PlayerKart : public Kart
|
||||
{
|
||||
private:
|
||||
int m_steer_val, m_steer_val_l, m_steer_val_r, m_accel_val;
|
||||
int m_steer_val, m_steer_val_l, m_steer_val_r;
|
||||
|
||||
Player *m_player;
|
||||
float m_penalty_time;
|
||||
|
@ -44,7 +44,8 @@ RaceManager::RaceManager()
|
||||
m_score_for_position = stk_config->m_scores;
|
||||
m_coin_target = 0;
|
||||
setTrack("race");
|
||||
setLocalPlayerKart(0, "tuxkart");
|
||||
setNumLocalPlayers(1);
|
||||
setLocalKartInfo(0, "tuxkart");
|
||||
} // RaceManager
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -60,38 +61,31 @@ void RaceManager::reset()
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceManager::setLocalPlayerKart(unsigned int player, const std::string& kart)
|
||||
void RaceManager::setPlayerKart(unsigned int player_id, const RemoteKartInfo& ki)
|
||||
{
|
||||
|
||||
if (player >= 0 && player < 4)
|
||||
{
|
||||
if (player >= getNumLocalPlayers())
|
||||
setNumLocalPlayers(player+1);
|
||||
m_local_player_karts[player].setPlayerId(player);
|
||||
m_local_player_karts[player].setKartName(kart);
|
||||
m_local_player_karts[player].setClientId(network_manager->getClientId());
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Warning: player '%d' does not exists.\n", player);
|
||||
}
|
||||
} // setLocalPlayerKart
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceManager::setPlayerKart(unsigned int player, const std::string& kart,
|
||||
const std::string& player_name, int host_id)
|
||||
{
|
||||
if (player >= getNumPlayers())
|
||||
setNumPlayers(player+1);
|
||||
m_player_karts[player] = kart;
|
||||
m_player_karts[player_id] = ki;
|
||||
} // setPlayerKart
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void RaceManager::setLocalKartInfo(unsigned int player_id, const std::string& kart)
|
||||
{
|
||||
assert(0<=player_id && player_id <m_local_kart_info.size());
|
||||
|
||||
m_local_kart_info[player_id]=RemoteKartInfo(player_id, kart,
|
||||
user_config->m_player[player_id].getName(),
|
||||
network_manager->getMyHostId());
|
||||
} // setLocalKartInfo
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceManager::setNumLocalPlayers(unsigned int n)
|
||||
{
|
||||
m_local_kart_info.resize(n);
|
||||
} // setNumLocalPlayers
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceManager::setNumPlayers(int num)
|
||||
{
|
||||
m_player_karts.resize(num);
|
||||
for(PlayerKarts::iterator i = m_player_karts.begin(); i != m_player_karts.end(); ++i)
|
||||
if (i->empty()) *i = "tuxkart";
|
||||
|
||||
} // setNumPlayers
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -170,7 +164,6 @@ void RaceManager::startNew()
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceManager::startNextRace()
|
||||
{
|
||||
|
||||
m_num_finished_karts = 0;
|
||||
m_num_finished_players = 0;
|
||||
|
||||
|
@ -1025,7 +1025,7 @@ ActionMap *UserConfig::newIngameActionMap()
|
||||
|
||||
GameAction gaEnd = GA_NULL;
|
||||
|
||||
switch (race_manager->getNumPlayers())
|
||||
switch (race_manager->getNumLocalPlayers())
|
||||
{
|
||||
case 1:
|
||||
gaEnd = GA_P1_LOOK_BACK; break;
|
||||
|
67
src/utils/random_generator.cpp
Normal file
67
src/utils/random_generator.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
// $Id: randum_number.cpp 2163 2008-07-14 03:40:58Z hikerstk $
|
||||
//
|
||||
// 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 "random_generator.hpp"
|
||||
|
||||
std::vector<RandomGenerator*> RandomGenerator::m_all_random_generators;
|
||||
|
||||
RandomGenerator::RandomGenerator()
|
||||
{
|
||||
m_a = 1103515245;
|
||||
m_c = 12345;
|
||||
m_all_random_generators.push_back(this);
|
||||
} // RandomGenerator
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
std::vector<int> RandomGenerator::generateAllSeeds()
|
||||
{
|
||||
std::vector<int> all_seeds;
|
||||
for(unsigned int i=0; i<m_all_random_generators.size(); i++)
|
||||
{
|
||||
int seed = rand();
|
||||
all_seeds.push_back(seed);
|
||||
}
|
||||
seedAll(all_seeds);
|
||||
return all_seeds;
|
||||
|
||||
} // generateAllSeeds
|
||||
// ----------------------------------------------------------------------------
|
||||
void RandomGenerator::seedAll(std::vector<int> all_seeds)
|
||||
{
|
||||
for(unsigned int i=0; i<all_seeds.size(); i++)
|
||||
{
|
||||
m_all_random_generators[i]->seed(all_seeds[i]);
|
||||
}
|
||||
} // seed
|
||||
|
||||
// -------------------q---------------------------------------------------------
|
||||
void RandomGenerator::seed(int s)
|
||||
{
|
||||
m_random_value = s;
|
||||
} // seed
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
int RandomGenerator::get(int n)
|
||||
{
|
||||
m_random_value = m_random_value*m_a+m_c;
|
||||
return m_random_value % n;
|
||||
} // get
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
49
src/utils/random_generator.hpp
Normal file
49
src/utils/random_generator.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
// $Id: randum_number.hpp 2163 2008-07-14 03:40:58Z hikerstk $
|
||||
//
|
||||
// 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_RANDOM_NUMBER_H
|
||||
#define HEADER_RANDOM_NUMBER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
/** A random number generator. Each objects that needs a random number uses
|
||||
its own number random generator. They are all seeded with number provided
|
||||
by the server. This guarantees that in a network game all 'random' values
|
||||
are actually identical among all machines.
|
||||
The formula used is x(n+1)=(a*x(n)+c) % m, but m is assumed to be 2^32,
|
||||
so the modulo operation can be skipped (for 4 byte integers).
|
||||
*/
|
||||
class RandomGenerator
|
||||
{
|
||||
private:
|
||||
unsigned int m_random_value;
|
||||
unsigned int m_a, m_c;
|
||||
static std::vector<RandomGenerator*> m_all_random_generators;
|
||||
public:
|
||||
RandomGenerator();
|
||||
static void seedAll(std::vector<int> all_seeds);
|
||||
std::vector<int> generateAllSeeds();
|
||||
void seed(int s);
|
||||
/** Returns a pseudo random number between 0 and n-1 inclusive */
|
||||
int get (int n);
|
||||
|
||||
|
||||
}; // RandomGenerator
|
||||
#endif
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "camera.hpp"
|
||||
#include "robots/default_robot.hpp"
|
||||
#include "unlock_manager.hpp"
|
||||
#include "network/network_kart.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#ifdef HAVE_GHOST_REPLAY
|
||||
# include "replay_player.hpp"
|
||||
@ -98,6 +97,7 @@ World::World()
|
||||
loadTrack() ;
|
||||
|
||||
m_player_karts.resize(race_manager->getNumPlayers());
|
||||
m_network_karts.resize(race_manager->getNumPlayers());
|
||||
m_local_player_karts.resize(race_manager->getNumLocalPlayers());
|
||||
|
||||
for(unsigned int i=0; i<race_manager->getNumKarts(); i++)
|
||||
@ -141,6 +141,7 @@ World::World()
|
||||
newkart = new NetworkKart(kart_name, position, init_pos,
|
||||
global_player_id);
|
||||
}
|
||||
m_network_karts[global_player_id] = static_cast<NetworkKart*>(newkart);
|
||||
break;
|
||||
case RaceManager::KT_AI:
|
||||
newkart = loadRobot(kart_name, position, init_pos);
|
||||
@ -347,10 +348,6 @@ void World::updateHighscores()
|
||||
// again by a faster kart in the same race), which might be confusing
|
||||
// if we ever decide to display a message (e.g. during a race)
|
||||
unsigned int *index = new unsigned int[m_kart.size()];
|
||||
#ifdef DEBUG
|
||||
// FIXME begin: for debugging only: had a bug here once, couldn't reproduce it:
|
||||
for(unsigned int i=0; i<m_kart.size(); i++) index[i]=-1;
|
||||
#endif
|
||||
for (unsigned int i=0; i<m_kart.size(); i++ )
|
||||
{
|
||||
index[m_kart[i]->getPosition()-1] = i;
|
||||
@ -817,9 +814,7 @@ Kart* World::loadRobot(const std::string& kart_name, int position,
|
||||
|
||||
const int NUM_ROBOTS = 1;
|
||||
|
||||
srand((unsigned)std::time(0));
|
||||
|
||||
switch(rand() % NUM_ROBOTS)
|
||||
switch(m_random.get(NUM_ROBOTS))
|
||||
{
|
||||
case 0:
|
||||
currentRobot = new DefaultRobot(kart_name, position, init_pos);
|
||||
|
@ -28,6 +28,9 @@
|
||||
#include "physics.hpp"
|
||||
#include "kart.hpp"
|
||||
#include "highscores.hpp"
|
||||
#include "network/network_kart.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
|
||||
#ifdef HAVE_GHOST_REPLAY
|
||||
# include "replay_recorder.hpp"
|
||||
class ReplayPlayer;
|
||||
@ -80,7 +83,9 @@ public:
|
||||
void disableRace(); // Put race into limbo phase
|
||||
|
||||
PlayerKart *getPlayerKart(int player) const { return m_player_karts[player]; }
|
||||
unsigned int getCurrentNumLocalPlayers() const {return m_local_player_karts.size();}
|
||||
PlayerKart *getLocalPlayerKart(int n) const { return m_local_player_karts[n]; }
|
||||
NetworkKart*getNetworkKart(int n) const {return m_network_karts[n]; }
|
||||
Kart *getKart(int kartId) const { assert(kartId >= 0 &&
|
||||
kartId < int(m_kart.size()));
|
||||
return m_kart[kartId]; }
|
||||
@ -103,9 +108,12 @@ public:
|
||||
void unpause();
|
||||
|
||||
private:
|
||||
Karts m_kart;
|
||||
std::vector<PlayerKart*> m_player_karts;
|
||||
std::vector<PlayerKart*> m_local_player_karts;
|
||||
std::vector<NetworkKart*> m_network_karts;
|
||||
RandomGenerator m_random;
|
||||
|
||||
Karts m_kart;
|
||||
Physics* m_physics;
|
||||
float m_fastest_lap;
|
||||
Kart* m_fastest_kart;
|
||||
|
Loading…
x
Reference in New Issue
Block a user