first iteration of new game mode code. most things seem okay, maybe high scores/rankings should be double-checked, also the end-of-race screen seems a bit messed up
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2287 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
164a7b87cf
commit
67c514f1ed
@ -144,6 +144,8 @@ supertuxkart_SOURCES = main.cpp \
|
|||||||
gui/feature_unlocked.cpp gui/feature_unlocked.hpp \
|
gui/feature_unlocked.cpp gui/feature_unlocked.hpp \
|
||||||
gui/font.hpp gui/font.cpp \
|
gui/font.hpp gui/font.cpp \
|
||||||
robots/default_robot.cpp robots/default_robot.hpp \
|
robots/default_robot.cpp robots/default_robot.hpp \
|
||||||
|
modes/follow_the_leader.cpp modes/follow_the_leader.hpp \
|
||||||
|
modes/standard_race.cpp modes/standard_race.hpp \
|
||||||
replay_buffer_tpl.hpp \
|
replay_buffer_tpl.hpp \
|
||||||
replay_buffers.hpp replay_buffers.cpp \
|
replay_buffers.hpp replay_buffers.cpp \
|
||||||
replay_base.hpp replay_base.cpp \
|
replay_base.hpp replay_base.cpp \
|
||||||
@ -162,9 +164,5 @@ supertuxkart_LDADD = -L. -lstatic_ssg \
|
|||||||
-lplibjs -lplibsl -lplibssg -lplibpu -lplibfnt -lplibsg \
|
-lplibjs -lplibsl -lplibssg -lplibpu -lplibfnt -lplibsg \
|
||||||
-lplibul -lplibssgaux $(bullet_LIBS) $(enet_LIBS) $(opengl_LIBS) $(sdl_LIBS) $(openal_LIBS)
|
-lplibul -lplibssgaux $(bullet_LIBS) $(enet_LIBS) $(opengl_LIBS) $(sdl_LIBS) $(openal_LIBS)
|
||||||
|
|
||||||
.PHONY: pot
|
|
||||||
pot:
|
|
||||||
xgettext -o supertuxkart.pot -k_ --c++ *.?pp */*.?pp
|
|
||||||
|
|
||||||
SUBDIRS = robots
|
SUBDIRS = robots
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ void Camera::update (float dt)
|
|||||||
kart_hpr.setRoll(0.0f);
|
kart_hpr.setRoll(0.0f);
|
||||||
// Only adjust the pitch if it's not the race start, otherwise
|
// Only adjust the pitch if it's not the race start, otherwise
|
||||||
// the camera will change pitch during ready-set-go.
|
// the camera will change pitch during ready-set-go.
|
||||||
if(world->isRacePhase())
|
if(world->getClock().isRacePhase())
|
||||||
{
|
{
|
||||||
// If the terrain pitch is 'significantly' different from the camera angle,
|
// If the terrain pitch is 'significantly' different from the camera angle,
|
||||||
// start adjusting the camera. This helps with steep declines, where
|
// start adjusting the camera. This helps with steep declines, where
|
||||||
|
@ -311,14 +311,6 @@ std::string FileManager::getHighscoreFile(const std::string& fname) const
|
|||||||
{
|
{
|
||||||
return getHomeDir()+"/"+fname;
|
return getHomeDir()+"/"+fname;
|
||||||
} // getHighscoreFile
|
} // getHighscoreFile
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
std::string FileManager::getReplayFile(const std::string& fname) const
|
|
||||||
{
|
|
||||||
return m_root_dir+"/replay/"+fname;
|
|
||||||
} // getReplayFile
|
|
||||||
#endif
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void FileManager::initConfigDir()
|
void FileManager::initConfigDir()
|
||||||
{
|
{
|
||||||
|
@ -59,9 +59,6 @@ public:
|
|||||||
std::string getSFXFile (const std::string& fname) const;
|
std::string getSFXFile (const std::string& fname) const;
|
||||||
std::string getFontFile (const std::string& fname) const;
|
std::string getFontFile (const std::string& fname) const;
|
||||||
std::string getModelFile (const std::string& fname) const;
|
std::string getModelFile (const std::string& fname) const;
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
std::string getReplayFile (const std::string& fname) const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void listFiles(std::set<std::string>& result, const std::string& dir,
|
void listFiles(std::set<std::string>& result, const std::string& dir,
|
||||||
bool is_full_path=false, bool make_full_path=false)
|
bool is_full_path=false, bool make_full_path=false)
|
||||||
|
@ -260,8 +260,9 @@ void RaceGUI::drawFPS ()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void RaceGUI::drawTimer ()
|
void RaceGUI::drawTimer ()
|
||||||
{
|
{
|
||||||
if(world->getPhase()!=World::RACE_PHASE &&
|
// if(world->getPhase() != RACE_PHASE &&
|
||||||
world->getPhase()!=World::DELAY_FINISH_PHASE ) return;
|
// world->getPhase() != DELAY_FINISH_PHASE ) return;
|
||||||
|
if(!world->shouldDrawTimer()) return;
|
||||||
char str[256];
|
char str[256];
|
||||||
|
|
||||||
assert(world != NULL);
|
assert(world != NULL);
|
||||||
@ -922,7 +923,7 @@ void RaceGUI::drawStatusText(const float dt)
|
|||||||
glOrtho ( 0, user_config->m_width, 0, user_config->m_height, 0, 100 ) ;
|
glOrtho ( 0, user_config->m_width, 0, user_config->m_height, 0, 100 ) ;
|
||||||
switch (world->getPhase())
|
switch (world->getPhase())
|
||||||
{
|
{
|
||||||
case World::READY_PHASE:
|
case READY_PHASE:
|
||||||
{
|
{
|
||||||
GLfloat const COLORS[] = { 0.9f, 0.66f, 0.62f, 1.0f };
|
GLfloat const COLORS[] = { 0.9f, 0.66f, 0.62f, 1.0f };
|
||||||
//I18N: as in "ready, set, go", shown at the beginning of the race
|
//I18N: as in "ready, set, go", shown at the beginning of the race
|
||||||
@ -932,7 +933,7 @@ void RaceGUI::drawStatusText(const float dt)
|
|||||||
COLORS );
|
COLORS );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case World::SET_PHASE:
|
case SET_PHASE:
|
||||||
{
|
{
|
||||||
GLfloat const COLORS[] = { 0.9f, 0.9f, 0.62f, 1.0f };
|
GLfloat const COLORS[] = { 0.9f, 0.9f, 0.62f, 1.0f };
|
||||||
//I18N: as in "ready, set, go", shown at the beginning of the race
|
//I18N: as in "ready, set, go", shown at the beginning of the race
|
||||||
@ -942,7 +943,7 @@ void RaceGUI::drawStatusText(const float dt)
|
|||||||
COLORS );
|
COLORS );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case World::GO_PHASE:
|
case GO_PHASE:
|
||||||
{
|
{
|
||||||
GLfloat const COLORS[] = { 0.39f, 0.82f, 0.39f, 1.0f };
|
GLfloat const COLORS[] = { 0.39f, 0.82f, 0.39f, 1.0f };
|
||||||
//I18N: as in "ready, set, go", shown at the beginning of the race
|
//I18N: as in "ready, set, go", shown at the beginning of the race
|
||||||
@ -968,7 +969,7 @@ void RaceGUI::drawStatusText(const float dt)
|
|||||||
// The penalty message needs to be displayed for up to one second
|
// The penalty message needs to be displayed for up to one second
|
||||||
// after the start of the race, otherwise it disappears if
|
// after the start of the race, otherwise it disappears if
|
||||||
// "Go" is displayed and the race starts
|
// "Go" is displayed and the race starts
|
||||||
if(world->isStartPhase() || world->getTime()<1.0f)
|
if(world->getClock().isStartPhase() || world->getTime()<1.0f)
|
||||||
{
|
{
|
||||||
for(unsigned int i=0; i<race_manager->getNumLocalPlayers(); i++)
|
for(unsigned int i=0; i<race_manager->getNumLocalPlayers(); i++)
|
||||||
{
|
{
|
||||||
@ -989,7 +990,7 @@ void RaceGUI::drawStatusText(const float dt)
|
|||||||
if(race_manager->getNumLocalPlayers() >= 3)
|
if(race_manager->getNumLocalPlayers() >= 3)
|
||||||
split_screen_ratio_x = 0.5;
|
split_screen_ratio_x = 0.5;
|
||||||
|
|
||||||
if ( world->isRacePhase() )
|
if ( world->getClock().isRacePhase() )
|
||||||
{
|
{
|
||||||
const int numPlayers = race_manager->getNumLocalPlayers();
|
const int numPlayers = race_manager->getNumLocalPlayers();
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -120,11 +120,11 @@ void MainLoop::run()
|
|||||||
if(user_config->m_profile) dt=1.0f/60.0f;
|
if(user_config->m_profile) dt=1.0f/60.0f;
|
||||||
// In the first call dt might be large (includes loading time),
|
// In the first call dt might be large (includes loading time),
|
||||||
// which can cause the camera to significantly tilt
|
// which can cause the camera to significantly tilt
|
||||||
scene->draw(world->getPhase()==World::SETUP_PHASE ? 0.0f : dt);
|
scene->draw(world->getPhase()==SETUP_PHASE ? 0.0f : dt);
|
||||||
|
|
||||||
network_manager->receiveUpdates();
|
network_manager->receiveUpdates();
|
||||||
|
|
||||||
if ( world->getPhase() != World::LIMBO_PHASE)
|
if ( world->getPhase() != LIMBO_PHASE)
|
||||||
{
|
{
|
||||||
world->update(dt);
|
world->update(dt);
|
||||||
|
|
||||||
|
114
src/modes/follow_the_leader.cpp
Normal file
114
src/modes/follow_the_leader.cpp
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2004 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 "modes/follow_the_leader.hpp"
|
||||||
|
#include "unlock_manager.hpp"
|
||||||
|
#include "gui/menu_manager.hpp"
|
||||||
|
#include "user_config.hpp"
|
||||||
|
|
||||||
|
// -----------------------------
|
||||||
|
FollowTheLeaderRace::FollowTheLeaderRace() : World(), ClockListener()
|
||||||
|
{
|
||||||
|
m_leader_intervals = stk_config->m_leader_intervals;
|
||||||
|
|
||||||
|
m_clock.registerEventListener(this);
|
||||||
|
m_clock.setMode(COUNTDOWN, m_leader_intervals[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------
|
||||||
|
FollowTheLeaderRace::~FollowTheLeaderRace()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FollowTheLeaderRace::restartRace()
|
||||||
|
{
|
||||||
|
World::restartRace();
|
||||||
|
m_leader_intervals = stk_config->m_leader_intervals;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clock events
|
||||||
|
void FollowTheLeaderRace::countdownReachedZero()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FollowTheLeaderRace::onGo()
|
||||||
|
{
|
||||||
|
// Reset the brakes now that the prestart
|
||||||
|
// phase is over (braking prevents the karts
|
||||||
|
// from sliding downhill)
|
||||||
|
for(unsigned int i=0; i<m_kart.size(); i++)
|
||||||
|
{
|
||||||
|
m_kart[i]->resetBrakes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FollowTheLeaderRace::update(float delta)
|
||||||
|
{
|
||||||
|
m_clock.updateClock(delta);
|
||||||
|
|
||||||
|
World::update(delta);
|
||||||
|
if(!m_clock.isRacePhase()) return;
|
||||||
|
|
||||||
|
if(m_clock.getTime() < 0.0f)
|
||||||
|
{
|
||||||
|
if(m_leader_intervals.size()>1)
|
||||||
|
m_leader_intervals.erase(m_leader_intervals.begin());
|
||||||
|
m_clock.setTime(m_leader_intervals[0]);
|
||||||
|
int kart_number;
|
||||||
|
// If the leader kart is not the first kart, remove the first
|
||||||
|
// kart, otherwise remove the last kart.
|
||||||
|
int position_to_remove = m_kart[0]->getPosition()==1
|
||||||
|
? getCurrentNumKarts() : 1;
|
||||||
|
for (kart_number=0; kart_number<(int)m_kart.size(); kart_number++)
|
||||||
|
{
|
||||||
|
if(m_kart[kart_number]->isEliminated()) continue;
|
||||||
|
if(m_kart[kart_number]->getPosition()==position_to_remove)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(kart_number==(int)m_kart.size())
|
||||||
|
{
|
||||||
|
fprintf(stderr,"Problem with removing leader: position %d not found\n",
|
||||||
|
position_to_remove);
|
||||||
|
for(int i=0; i<(int)m_kart.size(); i++)
|
||||||
|
{
|
||||||
|
fprintf(stderr,"kart %d: eliminated %d position %d\n",
|
||||||
|
i,m_kart[i]->isEliminated(), m_kart[i]->getPosition());
|
||||||
|
} // for i
|
||||||
|
} // kart_number==m_kart.size()
|
||||||
|
else
|
||||||
|
{
|
||||||
|
removeKart(kart_number);
|
||||||
|
}
|
||||||
|
// The follow the leader race is over if there is only one kart left,
|
||||||
|
// or if all players have gone
|
||||||
|
if(getCurrentNumKarts()==2 || getCurrentNumPlayers()==0)
|
||||||
|
{
|
||||||
|
// Add the results for the remaining kart
|
||||||
|
for(int i=1; i<(int)race_manager->getNumKarts(); i++)
|
||||||
|
if(!m_kart[i]->isEliminated())
|
||||||
|
race_manager->RaceFinished(m_kart[i], m_clock.getTime());
|
||||||
|
|
||||||
|
m_clock.raceOver();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FollowTheLeaderRace::onTerminate()
|
||||||
|
{
|
||||||
|
World::terminateRace();
|
||||||
|
}
|
41
src/modes/follow_the_leader.hpp
Normal file
41
src/modes/follow_the_leader.hpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2004 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 _follow_the_leader_hpp_
|
||||||
|
#define _follow_the_leader_hpp_
|
||||||
|
|
||||||
|
#include "world.hpp"
|
||||||
|
|
||||||
|
class FollowTheLeaderRace : public World, public ClockListener
|
||||||
|
{
|
||||||
|
std::vector<float> m_leader_intervals; // time till elimination in follow leader
|
||||||
|
public:
|
||||||
|
FollowTheLeaderRace();
|
||||||
|
~FollowTheLeaderRace();
|
||||||
|
|
||||||
|
// clock events
|
||||||
|
virtual void countdownReachedZero();
|
||||||
|
virtual void onGo();
|
||||||
|
virtual void onTerminate();
|
||||||
|
|
||||||
|
// overriding World methods
|
||||||
|
virtual void update(float delta);
|
||||||
|
virtual void restartRace();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
82
src/modes/standard_race.cpp
Normal file
82
src/modes/standard_race.cpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2006 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 "modes/standard_race.hpp"
|
||||||
|
#include "user_config.hpp"
|
||||||
|
#include "unlock_manager.hpp"
|
||||||
|
#include "gui/menu_manager.hpp"
|
||||||
|
|
||||||
|
// -----------------------------
|
||||||
|
StandardRace::StandardRace() : World(), ClockListener()
|
||||||
|
{
|
||||||
|
m_clock.registerEventListener(this);
|
||||||
|
m_clock.setMode(CHRONO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------
|
||||||
|
StandardRace::~StandardRace()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// clock events
|
||||||
|
void StandardRace::countdownReachedZero() { }
|
||||||
|
|
||||||
|
void StandardRace::onGo()
|
||||||
|
{
|
||||||
|
// Reset the brakes now that the prestart
|
||||||
|
// phase is over (braking prevents the karts
|
||||||
|
// from sliding downhill)
|
||||||
|
for(unsigned int i=0; i<m_kart.size(); i++)
|
||||||
|
{
|
||||||
|
m_kart[i]->resetBrakes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardRace::restartRace()
|
||||||
|
{
|
||||||
|
World::restartRace();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardRace::update(float delta)
|
||||||
|
{
|
||||||
|
m_clock.updateClock(delta);
|
||||||
|
|
||||||
|
World::update(delta);
|
||||||
|
if(!m_clock.isRacePhase()) return;
|
||||||
|
|
||||||
|
// =========================================================
|
||||||
|
if(race_manager->getFinishedKarts() >= race_manager->getNumKarts() )
|
||||||
|
{
|
||||||
|
m_clock.raceOver();
|
||||||
|
if(user_config->m_profile<0) printProfileResultAndExit();
|
||||||
|
unlock_manager->raceFinished();
|
||||||
|
} // if all karts are finished
|
||||||
|
|
||||||
|
// All player karts are finished, but computer still racing
|
||||||
|
// ===========================================================
|
||||||
|
else if(race_manager->allPlayerFinished())
|
||||||
|
{
|
||||||
|
// Set delay mode to have time for camera animation, and
|
||||||
|
// to give the AI some time to get non-estimated timings
|
||||||
|
m_clock.raceOver(true /* delay */);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardRace::onTerminate()
|
||||||
|
{
|
||||||
|
World::terminateRace();
|
||||||
|
}
|
39
src/modes/standard_race.hpp
Normal file
39
src/modes/standard_race.hpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2004 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 _standard_race_
|
||||||
|
#define _standard_race_
|
||||||
|
|
||||||
|
#include "world.hpp"
|
||||||
|
|
||||||
|
class StandardRace : public World, public ClockListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StandardRace();
|
||||||
|
~StandardRace();
|
||||||
|
|
||||||
|
// clock events
|
||||||
|
virtual void countdownReachedZero();
|
||||||
|
virtual void onGo();
|
||||||
|
virtual void onTerminate();
|
||||||
|
|
||||||
|
// overriding World methods
|
||||||
|
virtual void update(float delta);
|
||||||
|
virtual void restartRace();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -171,7 +171,7 @@ void PlayerKart::update(float dt)
|
|||||||
{
|
{
|
||||||
steer(dt, m_steer_val);
|
steer(dt, m_steer_val);
|
||||||
|
|
||||||
if(world->isStartPhase())
|
if(world->getClock().isStartPhase())
|
||||||
{
|
{
|
||||||
if(m_controls.accel!=0.0 || m_controls.brake!=false ||
|
if(m_controls.accel!=0.0 || m_controls.brake!=false ||
|
||||||
m_controls.fire|m_controls.wheelie|m_controls.jump)
|
m_controls.fire|m_controls.wheelie|m_controls.jump)
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include "user_config.hpp"
|
#include "user_config.hpp"
|
||||||
#include "stk_config.hpp"
|
#include "stk_config.hpp"
|
||||||
#include "network/network_manager.hpp"
|
#include "network/network_manager.hpp"
|
||||||
|
#include "modes/standard_race.hpp"
|
||||||
|
#include "modes/follow_the_leader.hpp"
|
||||||
|
|
||||||
RaceManager* race_manager= NULL;
|
RaceManager* race_manager= NULL;
|
||||||
|
|
||||||
@ -231,7 +233,15 @@ void RaceManager::startNextRace()
|
|||||||
// variable world. Admittedly a bit ugly, but simplifies
|
// variable world. Admittedly a bit ugly, but simplifies
|
||||||
// handling of objects which get created in the constructor
|
// handling of objects which get created in the constructor
|
||||||
// and need world to be defined.
|
// and need world to be defined.
|
||||||
new World();
|
|
||||||
|
/*
|
||||||
|
RM_GRAND_PRIX, RM_SINGLE,
|
||||||
|
RM_QUICK_RACE, RM_TIME_TRIAL, RM_FOLLOW_LEADER
|
||||||
|
FIXME
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(m_minor_mode==RM_FOLLOW_LEADER) new FollowTheLeaderRace();
|
||||||
|
else new StandardRace();
|
||||||
|
|
||||||
m_active_race = true;
|
m_active_race = true;
|
||||||
} // startNextRace
|
} // startNextRace
|
||||||
|
@ -97,7 +97,7 @@ void DefaultRobot::update( float delta )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( world->isStartPhase())
|
if( world->getClock().isStartPhase() )
|
||||||
{
|
{
|
||||||
handle_race_start();
|
handle_race_start();
|
||||||
AutoKart::update( delta );
|
AutoKart::update( delta );
|
||||||
@ -513,7 +513,7 @@ void DefaultRobot::handle_rescue(const float DELTA)
|
|||||||
|
|
||||||
|
|
||||||
// check if kart is stuck
|
// check if kart is stuck
|
||||||
if(getSpeed()<2.0f && !isRescue() && !world->isStartPhase())
|
if(getSpeed()<2.0f && !isRescue() && !world->getClock().isStartPhase())
|
||||||
{
|
{
|
||||||
m_time_since_stuck += DELTA;
|
m_time_since_stuck += DELTA;
|
||||||
if(m_time_since_stuck > 2.0f)
|
if(m_time_since_stuck > 2.0f)
|
||||||
|
@ -167,7 +167,7 @@ public:
|
|||||||
bool m_no_start_screen;
|
bool m_no_start_screen;
|
||||||
bool m_smoke;
|
bool m_smoke;
|
||||||
bool m_display_fps;
|
bool m_display_fps;
|
||||||
int m_profile; // Positive number: time in seconds, neg: # laps
|
int m_profile; // Positive number: time in seconds, neg: # laps. (used to profile AI)
|
||||||
bool m_print_kart_sizes; // print all kart sizes
|
bool m_print_kart_sizes; // print all kart sizes
|
||||||
// 0 if no profiling. Never saved in config file!
|
// 0 if no profiling. Never saved in config file!
|
||||||
bool m_skidding;
|
bool m_skidding;
|
||||||
|
485
src/world.cpp
485
src/world.cpp
@ -50,35 +50,174 @@
|
|||||||
#include "network/network_manager.hpp"
|
#include "network/network_manager.hpp"
|
||||||
#include "network/race_state.hpp"
|
#include "network/race_state.hpp"
|
||||||
|
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
# include "replay_player.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||||
# define snprintf _snprintf
|
# define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
World* world = 0;
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
Clock::Clock()
|
||||||
|
{
|
||||||
|
m_mode = CHRONO;
|
||||||
|
m_time = 0.0f;
|
||||||
|
m_auxiliary_timer = 0.0f;
|
||||||
|
m_listener = NULL;
|
||||||
|
m_phase = SETUP_PHASE;
|
||||||
|
m_previous_phase = SETUP_PHASE; // initialise it just in case
|
||||||
|
|
||||||
|
// for profiling AI
|
||||||
|
m_phase = user_config->m_profile ? RACE_PHASE : SETUP_PHASE;
|
||||||
|
|
||||||
|
// FIXME - is it a really good idea to reload and delete the sound every race??
|
||||||
|
m_prestart_sound = sfx_manager->newSFX(SFXManager::SOUND_PRESTART);
|
||||||
|
m_start_sound = sfx_manager->newSFX(SFXManager::SOUND_START);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Clock::reset()
|
||||||
|
{
|
||||||
|
m_time = 0.0f;
|
||||||
|
m_auxiliary_timer = 0.0f;
|
||||||
|
m_phase = READY_PHASE; // FIXME - unsure
|
||||||
|
m_previous_phase = SETUP_PHASE;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
Clock::~Clock()
|
||||||
|
{
|
||||||
|
sfx_manager->deleteSFX(m_prestart_sound);
|
||||||
|
sfx_manager->deleteSFX(m_start_sound);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Clock::setMode(const ClockType mode, const float initial_time)
|
||||||
|
{
|
||||||
|
m_mode = mode;
|
||||||
|
m_time = initial_time;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Clock::raceOver(const bool delay)
|
||||||
|
{
|
||||||
|
if(m_phase == DELAY_FINISH_PHASE or m_phase == FINISH_PHASE) return; // we already know
|
||||||
|
|
||||||
|
if(delay)
|
||||||
|
{
|
||||||
|
m_phase = DELAY_FINISH_PHASE;
|
||||||
|
m_auxiliary_timer = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_phase = FINISH_PHASE;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Clock::updateClock(const float dt)
|
||||||
|
{
|
||||||
|
switch(m_phase)
|
||||||
|
{
|
||||||
|
// Note: setup phase must be a separate phase, since the race_manager
|
||||||
|
// checks the phase when updating the camera: in the very first time
|
||||||
|
// step dt is large (it includes loading time), so the camera might
|
||||||
|
// tilt way too much. A separate setup phase for the first frame
|
||||||
|
// simplifies this handling
|
||||||
|
case SETUP_PHASE:
|
||||||
|
m_auxiliary_timer = 0.0f;
|
||||||
|
m_phase = READY_PHASE;
|
||||||
|
m_prestart_sound->play();
|
||||||
|
return; // loading time, don't play sound yet
|
||||||
|
case READY_PHASE:
|
||||||
|
if(m_auxiliary_timer>1.0)
|
||||||
|
{
|
||||||
|
m_phase=SET_PHASE;
|
||||||
|
m_prestart_sound->play();
|
||||||
|
}
|
||||||
|
m_auxiliary_timer += dt;
|
||||||
|
return;
|
||||||
|
case SET_PHASE :
|
||||||
|
if(m_auxiliary_timer>2.0)
|
||||||
|
{
|
||||||
|
// set phase is over, go to the next one
|
||||||
|
m_phase=GO_PHASE;
|
||||||
|
|
||||||
|
m_start_sound->play();
|
||||||
|
|
||||||
|
assert(m_listener != NULL);
|
||||||
|
m_listener -> onGo();
|
||||||
|
}
|
||||||
|
m_auxiliary_timer += dt;
|
||||||
|
return;
|
||||||
|
case GO_PHASE :
|
||||||
|
if(m_auxiliary_timer>3.0) // how long to display the 'go' message
|
||||||
|
m_phase=RACE_PHASE;
|
||||||
|
m_auxiliary_timer += dt;
|
||||||
|
break;
|
||||||
|
case DELAY_FINISH_PHASE :
|
||||||
|
{
|
||||||
|
m_auxiliary_timer += dt;
|
||||||
|
|
||||||
|
// Nothing more to do if delay time is not over yet
|
||||||
|
if(m_auxiliary_timer < TIME_DELAY_TILL_FINISH) break;
|
||||||
|
|
||||||
|
m_phase = FINISH_PHASE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FINISH_PHASE:
|
||||||
|
m_listener->onTerminate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(m_mode)
|
||||||
|
{
|
||||||
|
case CHRONO:
|
||||||
|
m_time += dt;
|
||||||
|
break;
|
||||||
|
case COUNTDOWN:
|
||||||
|
m_time -= dt;
|
||||||
|
|
||||||
|
if(m_time <= 0.0)
|
||||||
|
{
|
||||||
|
assert(m_listener != NULL);
|
||||||
|
m_listener -> countdownReachedZero();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Clock::setTime(const float time)
|
||||||
|
{
|
||||||
|
m_time = time;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Clock::registerEventListener(ClockListener* listener)
|
||||||
|
{
|
||||||
|
m_listener = listener;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Clock::pause()
|
||||||
|
{
|
||||||
|
m_previous_phase = m_phase;
|
||||||
|
m_phase = LIMBO_PHASE;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Clock::unpause()
|
||||||
|
{
|
||||||
|
m_phase = m_previous_phase;
|
||||||
|
}
|
||||||
|
|
||||||
|
World* world = 0; // FIXME, use singleton or something instead of this global variable
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
World::World()
|
World::World()
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
, m_p_replay_player(NULL)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
delete world;
|
delete world;
|
||||||
world = this;
|
world = this;
|
||||||
race_state = new RaceState();
|
race_state = new RaceState();
|
||||||
m_phase = SETUP_PHASE;
|
|
||||||
m_previous_phase = SETUP_PHASE; // initialise it just in case
|
|
||||||
m_track = NULL;
|
m_track = NULL;
|
||||||
m_clock = 0.0f;
|
|
||||||
m_faster_music_active = false;
|
m_faster_music_active = false;
|
||||||
m_fastest_lap = 9999999.9f;
|
m_fastest_lap = 9999999.9f;
|
||||||
m_fastest_kart = 0;
|
m_fastest_kart = 0;
|
||||||
m_eliminated_karts = 0;
|
m_eliminated_karts = 0;
|
||||||
m_eliminated_players = 0;
|
m_eliminated_players = 0;
|
||||||
m_leader_intervals = stk_config->m_leader_intervals;
|
|
||||||
|
|
||||||
|
m_clock.setMode( CHRONO );
|
||||||
|
|
||||||
// Grab the track file
|
// Grab the track file
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -176,33 +315,14 @@ World::World()
|
|||||||
callback_manager->initAll();
|
callback_manager->initAll();
|
||||||
menu_manager->switchToRace();
|
menu_manager->switchToRace();
|
||||||
|
|
||||||
m_prestart_sound = sfx_manager->newSFX(SFXManager::SOUND_PRESTART);
|
|
||||||
m_start_sound = sfx_manager->newSFX(SFXManager::SOUND_START);
|
|
||||||
|
|
||||||
m_track->startMusic();
|
m_track->startMusic();
|
||||||
|
|
||||||
m_phase = user_config->m_profile ? RACE_PHASE : SETUP_PHASE;
|
|
||||||
|
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
m_replay_recorder.initRecorder( race_manager->getNumKarts() );
|
|
||||||
|
|
||||||
m_p_replay_player = new ReplayPlayer;
|
|
||||||
if( !loadReplayHumanReadable( "test1" ) )
|
|
||||||
{
|
|
||||||
delete m_p_replay_player;
|
|
||||||
m_p_replay_player = NULL;
|
|
||||||
}
|
|
||||||
if( m_p_replay_player ) m_p_replay_player->showReplayAt( 0.0 );
|
|
||||||
#endif
|
|
||||||
network_manager->worldLoaded();
|
network_manager->worldLoaded();
|
||||||
} // World
|
} // World
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
World::~World()
|
World::~World()
|
||||||
{
|
{
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
saveReplayHumanReadable( "test" );
|
|
||||||
#endif
|
|
||||||
delete race_state;
|
delete race_state;
|
||||||
m_track->cleanup();
|
m_track->cleanup();
|
||||||
// Clear all callbacks
|
// Clear all callbacks
|
||||||
@ -216,8 +336,6 @@ World::~World()
|
|||||||
delete m_physics;
|
delete m_physics;
|
||||||
|
|
||||||
sound_manager -> stopMusic();
|
sound_manager -> stopMusic();
|
||||||
sfx_manager->deleteSFX(m_prestart_sound);
|
|
||||||
sfx_manager->deleteSFX(m_start_sound);
|
|
||||||
|
|
||||||
sgVec3 sun_pos;
|
sgVec3 sun_pos;
|
||||||
sgVec4 ambient_col, specular_col, diffuse_col;
|
sgVec4 ambient_col, specular_col, diffuse_col;
|
||||||
@ -230,18 +348,15 @@ World::~World()
|
|||||||
ssgGetLight ( 0 ) -> setColour ( GL_AMBIENT , ambient_col ) ;
|
ssgGetLight ( 0 ) -> setColour ( GL_AMBIENT , ambient_col ) ;
|
||||||
ssgGetLight ( 0 ) -> setColour ( GL_DIFFUSE , diffuse_col ) ;
|
ssgGetLight ( 0 ) -> setColour ( GL_DIFFUSE , diffuse_col ) ;
|
||||||
ssgGetLight ( 0 ) -> setColour ( GL_SPECULAR, specular_col ) ;
|
ssgGetLight ( 0 ) -> setColour ( GL_SPECULAR, specular_col ) ;
|
||||||
|
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
m_replay_recorder.destroy();
|
|
||||||
if( m_p_replay_player )
|
|
||||||
{
|
|
||||||
m_p_replay_player->destroy();
|
|
||||||
delete m_p_replay_player;
|
|
||||||
m_p_replay_player = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} // ~World
|
} // ~World
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void World::terminateRace()
|
||||||
|
{
|
||||||
|
m_clock.pause();
|
||||||
|
menu_manager->pushMenu(MENUID_RACERESULT);
|
||||||
|
estimateFinishTimes();
|
||||||
|
unlock_manager->raceFinished();
|
||||||
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Waits till each kart is resting on the ground
|
/** Waits till each kart is resting on the ground
|
||||||
*
|
*
|
||||||
@ -300,21 +415,7 @@ void World::update(float dt)
|
|||||||
// Clear race state so that new information can be stored
|
// Clear race state so that new information can be stored
|
||||||
race_state->clear();
|
race_state->clear();
|
||||||
if(user_config->m_replay_history) dt=history->GetNextDelta();
|
if(user_config->m_replay_history) dt=history->GetNextDelta();
|
||||||
updateRaceStatus(dt);
|
|
||||||
|
|
||||||
if( getPhase() == FINISH_PHASE )
|
|
||||||
{
|
|
||||||
if(race_manager->getMinorMode()==RaceManager::RM_FOLLOW_LEADER)
|
|
||||||
{
|
|
||||||
pause();
|
|
||||||
menu_manager->pushMenu(MENUID_RACERESULT);
|
|
||||||
unlock_manager->raceFinished();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
updateHighscores();
|
|
||||||
pause();
|
|
||||||
menu_manager->pushMenu(MENUID_RACERESULT);
|
|
||||||
}
|
|
||||||
if(!user_config->m_replay_history) history->StoreDelta(dt);
|
if(!user_config->m_replay_history) history->StoreDelta(dt);
|
||||||
if(network_manager->getMode()!=NetworkManager::NW_CLIENT) m_physics->update(dt);
|
if(network_manager->getMode()!=NetworkManager::NW_CLIENT) m_physics->update(dt);
|
||||||
for (int i = 0 ; i <(int) m_kart.size(); ++i)
|
for (int i = 0 ; i <(int) m_kart.size(); ++i)
|
||||||
@ -335,16 +436,6 @@ void World::update(float dt)
|
|||||||
|
|
||||||
/* Routine stuff we do even when paused */
|
/* Routine stuff we do even when paused */
|
||||||
callback_manager->update(dt);
|
callback_manager->update(dt);
|
||||||
|
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
// we start recording after START_PHASE, since during start-phase m_clock is incremented
|
|
||||||
// normally, but after switching to RACE_PHASE m_clock is set back to 0.0
|
|
||||||
if( m_phase == GO_PHASE )
|
|
||||||
{
|
|
||||||
m_replay_recorder.pushFrame();
|
|
||||||
if( m_p_replay_player ) m_p_replay_player->showReplayAt( m_clock );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void World::updateHighscores()
|
void World::updateHighscores()
|
||||||
@ -373,7 +464,6 @@ void World::updateHighscores()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// FIXME: end
|
|
||||||
|
|
||||||
// Only record times for player karts
|
// Only record times for player karts
|
||||||
if(!m_kart[index[pos]]->isPlayerKart()) continue;
|
if(!m_kart[index[pos]]->isPlayerKart()) continue;
|
||||||
@ -394,180 +484,6 @@ void World::updateHighscores()
|
|||||||
delete []index;
|
delete []index;
|
||||||
} // updateHighscores
|
} // updateHighscores
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
bool World::saveReplayHumanReadable( std::string const &filename ) const
|
|
||||||
{
|
|
||||||
std::string path;
|
|
||||||
path = file_manager->getReplayFile(filename+"."+ReplayBase::REPLAY_FILE_EXTENSION_HUMAN_READABLE);
|
|
||||||
|
|
||||||
FILE *fd = fopen( path.c_str(), "w" );
|
|
||||||
if( !fd )
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error while opening replay file for writing '%s'\n", path.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int nKarts = world->getNumKarts();
|
|
||||||
const char *version = "unknown";
|
|
||||||
#ifdef VERSION
|
|
||||||
version = VERSION;
|
|
||||||
#endif
|
|
||||||
fprintf(fd, "Version: %s\n", version);
|
|
||||||
fprintf(fd, "numkarts: %d\n", m_kart.size());
|
|
||||||
fprintf(fd, "numplayers: %d\n", race_manager->getNumPlayers());
|
|
||||||
fprintf(fd, "difficulty: %d\n", race_manager->getDifficulty());
|
|
||||||
fprintf(fd, "track: %s\n", m_track->getIdent().c_str());
|
|
||||||
|
|
||||||
for(int i=0; i<race_manager->getNumKarts(); i++)
|
|
||||||
{
|
|
||||||
fprintf(fd, "model %d: %s\n", i, race_manager->getKartName(i).c_str());
|
|
||||||
}
|
|
||||||
if( !m_replay_recorder.saveReplayHumanReadable( fd ) )
|
|
||||||
{
|
|
||||||
fclose( fd ); fd = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose( fd ); fd = NULL;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} // saveReplayHumanReadable
|
|
||||||
#endif // HAVE_GHOST_REPLAY
|
|
||||||
|
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
bool World::loadReplayHumanReadable( std::string const &filename )
|
|
||||||
{
|
|
||||||
assert( m_p_replay_player );
|
|
||||||
m_p_replay_player->destroy();
|
|
||||||
|
|
||||||
std::string path = file_manager->getReplayFile(filename+"."+
|
|
||||||
ReplayBase::REPLAY_FILE_EXTENSION_HUMAN_READABLE);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
path = file_manager->getPath(path.c_str());
|
|
||||||
}
|
|
||||||
catch(std::runtime_error& e)
|
|
||||||
{
|
|
||||||
fprintf( stderr, "Couldn't find replay-file: '%s'\n", path.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *fd = fopen( path.c_str(), "r" );
|
|
||||||
if( !fd )
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error while opening replay file for loading '%s'\n", path.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool blnRet = m_p_replay_player->loadReplayHumanReadable( fd );
|
|
||||||
|
|
||||||
fclose( fd ); fd = NULL;
|
|
||||||
|
|
||||||
return blnRet;
|
|
||||||
} // loadReplayHumanReadable
|
|
||||||
#endif // HAVE_GHOST_REPLAY
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void World::updateRaceStatus(float dt)
|
|
||||||
{
|
|
||||||
switch (m_phase) {
|
|
||||||
// Note: setup phase must be a separate phase, since the race_manager
|
|
||||||
// checks the phase when updating the camera: in the very first time
|
|
||||||
// step dt is large (it includes loading time), so the camera might
|
|
||||||
// tilt way too much. A separate setup phase for the first frame
|
|
||||||
// simplifies this handling
|
|
||||||
case SETUP_PHASE: m_clock = 0.0f;
|
|
||||||
m_phase = READY_PHASE;
|
|
||||||
m_prestart_sound->play();
|
|
||||||
dt = 0.0f; // solves the problem of adding track loading time
|
|
||||||
return; // loading time, don't play sound yet
|
|
||||||
case READY_PHASE: if(m_clock>1.0)
|
|
||||||
{
|
|
||||||
m_phase=SET_PHASE;
|
|
||||||
m_prestart_sound->play();
|
|
||||||
}
|
|
||||||
m_clock += dt;
|
|
||||||
return;
|
|
||||||
case SET_PHASE : if(m_clock>2.0)
|
|
||||||
{
|
|
||||||
m_phase=GO_PHASE;
|
|
||||||
if(race_manager->getMinorMode()==RaceManager::RM_FOLLOW_LEADER)
|
|
||||||
m_clock=m_leader_intervals[0];
|
|
||||||
else
|
|
||||||
m_clock=0.0f;
|
|
||||||
m_start_sound->play();
|
|
||||||
// Reset the brakes now that the prestart
|
|
||||||
// phase is over (braking prevents the karts
|
|
||||||
// from sliding downhill)
|
|
||||||
for(unsigned int i=0; i<m_kart.size(); i++)
|
|
||||||
{
|
|
||||||
m_kart[i]->resetBrakes();
|
|
||||||
}
|
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
// push positions at time 0.0 to replay-data
|
|
||||||
m_replay_recorder.pushFrame();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
m_clock += dt;
|
|
||||||
return;
|
|
||||||
case GO_PHASE : if(race_manager->getMinorMode()==RaceManager::RM_FOLLOW_LEADER)
|
|
||||||
{
|
|
||||||
// Switch to race if more than 1 second has past
|
|
||||||
if(m_clock<m_leader_intervals[0]-1.0f)
|
|
||||||
m_phase=RACE_PHASE;
|
|
||||||
m_clock -= dt;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(m_clock>1.0) // how long to display the 'go' message
|
|
||||||
m_phase=RACE_PHASE;
|
|
||||||
m_clock += dt;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case DELAY_FINISH_PHASE :
|
|
||||||
{
|
|
||||||
m_clock += dt;
|
|
||||||
// Nothing more to do if delay time is not over yet
|
|
||||||
if(m_clock - m_finish_delay_start_time
|
|
||||||
< TIME_DELAY_TILL_FINISH) return;
|
|
||||||
|
|
||||||
m_phase = FINISH_PHASE;
|
|
||||||
estimateFinishTimes();
|
|
||||||
unlock_manager->raceFinished();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
default : break;
|
|
||||||
} // switch
|
|
||||||
|
|
||||||
if(race_manager->getMinorMode()==RaceManager::RM_FOLLOW_LEADER)
|
|
||||||
return updateLeaderMode(dt);
|
|
||||||
|
|
||||||
// The status must now be race mode!
|
|
||||||
// =================================
|
|
||||||
m_clock += dt;
|
|
||||||
|
|
||||||
// 2) A player comes in last, go immediately to finish phase
|
|
||||||
// =========================================================
|
|
||||||
if(race_manager->getFinishedKarts() >= race_manager->getNumKarts() )
|
|
||||||
{
|
|
||||||
m_phase = FINISH_PHASE;
|
|
||||||
if(user_config->m_profile<0) printProfileResultAndExit();
|
|
||||||
unlock_manager->raceFinished();
|
|
||||||
} // if all karts are finished
|
|
||||||
|
|
||||||
// 3) All player karts are finished, but computer still racing
|
|
||||||
// ===========================================================
|
|
||||||
else if(race_manager->allPlayerFinished())
|
|
||||||
{
|
|
||||||
// Set delay mode to have time for camera animation, and
|
|
||||||
// to give the AI some time to get non-estimated timings
|
|
||||||
m_phase = DELAY_FINISH_PHASE;
|
|
||||||
m_finish_delay_start_time = m_clock;
|
|
||||||
}
|
|
||||||
} // updateRaceStatus
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void World::estimateFinishTimes()
|
void World::estimateFinishTimes()
|
||||||
@ -582,60 +498,6 @@ void World::estimateFinishTimes()
|
|||||||
} // for i
|
} // for i
|
||||||
} // estimateFinishTimes
|
} // estimateFinishTimes
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void World::updateLeaderMode(float dt)
|
|
||||||
{
|
|
||||||
// Count 'normal' till race phase has started, then count backwards
|
|
||||||
if(m_phase==RACE_PHASE || m_phase==GO_PHASE)
|
|
||||||
m_clock -=dt;
|
|
||||||
else
|
|
||||||
m_clock +=dt;
|
|
||||||
if(m_clock<0.0f)
|
|
||||||
{
|
|
||||||
if(m_leader_intervals.size()>1)
|
|
||||||
m_leader_intervals.erase(m_leader_intervals.begin());
|
|
||||||
m_clock=m_leader_intervals[0];
|
|
||||||
int kart_number;
|
|
||||||
// If the leader kart is not the first kart, remove the first
|
|
||||||
// kart, otherwise remove the last kart.
|
|
||||||
int position_to_remove = m_kart[0]->getPosition()==1
|
|
||||||
? getCurrentNumKarts() : 1;
|
|
||||||
for (kart_number=0; kart_number<(int)m_kart.size(); kart_number++)
|
|
||||||
{
|
|
||||||
if(m_kart[kart_number]->isEliminated()) continue;
|
|
||||||
if(m_kart[kart_number]->getPosition()==position_to_remove)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(kart_number==(int)m_kart.size())
|
|
||||||
{
|
|
||||||
fprintf(stderr,"Problem with removing leader: position %d not found\n",
|
|
||||||
position_to_remove);
|
|
||||||
for(int i=0; i<(int)m_kart.size(); i++)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"kart %d: eliminated %d position %d\n",
|
|
||||||
i,m_kart[i]->isEliminated(), m_kart[i]->getPosition());
|
|
||||||
} // for i
|
|
||||||
} // kart_number==m_kart.size()
|
|
||||||
else
|
|
||||||
{
|
|
||||||
removeKart(kart_number);
|
|
||||||
}
|
|
||||||
// The follow the leader race is over if there is only one kart left,
|
|
||||||
// or if all players have gone
|
|
||||||
if(getCurrentNumKarts()==2 ||getCurrentNumPlayers()==0)
|
|
||||||
{
|
|
||||||
// Add the results for the remaining kart
|
|
||||||
for(int i=1; i<(int)race_manager->getNumKarts(); i++)
|
|
||||||
if(!m_kart[i]->isEliminated())
|
|
||||||
race_manager->RaceFinished(m_kart[i], m_clock);
|
|
||||||
m_phase=FINISH_PHASE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} // m_clock<0
|
|
||||||
return;
|
|
||||||
|
|
||||||
} // updateLeaderMode
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void World::printProfileResultAndExit()
|
void World::printProfileResultAndExit()
|
||||||
{
|
{
|
||||||
@ -694,7 +556,7 @@ void World::removeKart(int kart_number)
|
|||||||
// ignored in all loops). Important:world->getCurrentNumKarts() returns
|
// ignored in all loops). Important:world->getCurrentNumKarts() returns
|
||||||
// the number of karts still racing. This value can not be used for loops
|
// the number of karts still racing. This value can not be used for loops
|
||||||
// over all karts, use race_manager->getNumKarts() instead!
|
// over all karts, use race_manager->getNumKarts() instead!
|
||||||
race_manager->RaceFinished(kart, m_clock);
|
race_manager->RaceFinished(kart, m_clock.getTime());
|
||||||
kart->eliminate();
|
kart->eliminate();
|
||||||
m_eliminated_karts++;
|
m_eliminated_karts++;
|
||||||
|
|
||||||
@ -782,23 +644,25 @@ void World::loadTrack()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void World::restartRace()
|
void World::restartRace()
|
||||||
{
|
{
|
||||||
m_clock = 0.0f;
|
m_clock.reset();
|
||||||
m_phase = SETUP_PHASE;
|
|
||||||
m_previous_phase = SETUP_PHASE;
|
|
||||||
m_faster_music_active = false;
|
m_faster_music_active = false;
|
||||||
m_eliminated_karts = 0;
|
m_eliminated_karts = 0;
|
||||||
m_eliminated_players = 0;
|
m_eliminated_players = 0;
|
||||||
m_leader_intervals = stk_config->m_leader_intervals;
|
|
||||||
|
|
||||||
for ( Karts::iterator i = m_kart.begin(); i != m_kart.end() ; ++i )
|
for ( Karts::iterator i = m_kart.begin(); i != m_kart.end() ; ++i )
|
||||||
{
|
{
|
||||||
(*i)->reset();
|
(*i)->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
resetAllKarts();
|
resetAllKarts();
|
||||||
sound_manager->stopMusic(); // Start music from beginning
|
|
||||||
|
// Start music from beginning
|
||||||
|
sound_manager->stopMusic();
|
||||||
m_track->startMusic();
|
m_track->startMusic();
|
||||||
|
|
||||||
// Enable SFX again
|
// Enable SFX again
|
||||||
sfx_manager->resumeAll();
|
sfx_manager->resumeAll();
|
||||||
|
|
||||||
herring_manager->reset();
|
herring_manager->reset();
|
||||||
projectile_manager->cleanup();
|
projectile_manager->cleanup();
|
||||||
race_manager->reset();
|
race_manager->reset();
|
||||||
@ -806,16 +670,6 @@ void World::restartRace()
|
|||||||
|
|
||||||
// Resets the cameras in case that they are pointing too steep up or down
|
// Resets the cameras in case that they are pointing too steep up or down
|
||||||
scene->reset();
|
scene->reset();
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
m_replay_recorder.destroy();
|
|
||||||
m_replay_recorder.initRecorder( race_manager->getNumKarts() );
|
|
||||||
|
|
||||||
if( m_p_replay_player )
|
|
||||||
{
|
|
||||||
m_p_replay_player->reset();
|
|
||||||
m_p_replay_player->showReplayAt( 0.0 );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} // restartRace
|
} // restartRace
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -845,8 +699,7 @@ void World::pause()
|
|||||||
{
|
{
|
||||||
sound_manager->pauseMusic();
|
sound_manager->pauseMusic();
|
||||||
sfx_manager->pauseAll();
|
sfx_manager->pauseAll();
|
||||||
m_previous_phase = m_phase;
|
m_clock.pause();
|
||||||
m_phase = LIMBO_PHASE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -854,7 +707,7 @@ void World::unpause()
|
|||||||
{
|
{
|
||||||
sound_manager->resumeMusic() ;
|
sound_manager->resumeMusic() ;
|
||||||
sfx_manager->resumeAll();
|
sfx_manager->resumeAll();
|
||||||
m_phase = m_previous_phase;
|
m_clock.unpause();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
255
src/world.hpp
255
src/world.hpp
@ -32,11 +32,6 @@
|
|||||||
#include "network/network_kart.hpp"
|
#include "network/network_kart.hpp"
|
||||||
#include "utils/random_generator.hpp"
|
#include "utils/random_generator.hpp"
|
||||||
|
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
# include "replay_recorder.hpp"
|
|
||||||
class ReplayPlayer;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class SFXBase;
|
class SFXBase;
|
||||||
|
|
||||||
/** This class is responsible for running the actual race. A world is created
|
/** This class is responsible for running the actual race. A world is created
|
||||||
@ -78,117 +73,207 @@ class SFXBase;
|
|||||||
* would be done in the mode specific world (instead of in the
|
* would be done in the mode specific world (instead of in the
|
||||||
* RaceManager).
|
* RaceManager).
|
||||||
*/
|
*/
|
||||||
class World
|
enum ClockType
|
||||||
|
{
|
||||||
|
CLOCK_NONE,
|
||||||
|
CHRONO, // counts up
|
||||||
|
COUNTDOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abstract base class, derive from it to receive events from the clock
|
||||||
|
*/
|
||||||
|
class ClockListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::vector<Kart*> Karts;
|
virtual ~ClockListener(){};
|
||||||
|
/*
|
||||||
/** resources, this should be put in a separate class or replaced by a smart
|
* Will be called to notify your derived class that the clock,
|
||||||
* resource manager
|
* which is in COUNTDOWN mode, has reached zero.
|
||||||
*/
|
*/
|
||||||
|
virtual void countdownReachedZero() = 0;
|
||||||
enum Phase {
|
|
||||||
// Game setup, e.g. track loading
|
|
||||||
SETUP_PHASE,
|
|
||||||
// 'Ready' is displayed
|
|
||||||
READY_PHASE,
|
|
||||||
// 'Set' is displayed
|
|
||||||
SET_PHASE,
|
|
||||||
// 'Go' is displayed, but this is already race phase
|
|
||||||
GO_PHASE,
|
|
||||||
// the actual race has started, no ready/set/go is displayed anymore
|
|
||||||
RACE_PHASE,
|
|
||||||
// All players have finished, now wait a certain amount of time for AI
|
|
||||||
// karts to finish. If they do not finish in that time, finish the race
|
|
||||||
DELAY_FINISH_PHASE,
|
|
||||||
// The player crossed the finishing line and his and the time of
|
|
||||||
// the other players is displayed, controll is automatic
|
|
||||||
FINISH_PHASE,
|
|
||||||
// The state after finish where no calculations are done.
|
|
||||||
LIMBO_PHASE,
|
|
||||||
};
|
|
||||||
|
|
||||||
Track* m_track;
|
|
||||||
|
|
||||||
/** debug text that will be overlaid to the screen */
|
/*
|
||||||
std::string m_debug_text[10];
|
* Called when the race actually starts.
|
||||||
|
*/
|
||||||
|
virtual void onGo() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when race is over and should be terminated (mostly called by the clock).
|
||||||
|
*/
|
||||||
|
virtual void onTerminate() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
World();
|
enum Phase {
|
||||||
virtual ~World();
|
// Game setup, e.g. track loading
|
||||||
void update(float delta);
|
SETUP_PHASE,
|
||||||
// Note: GO_PHASE is both: start phase and race phase
|
// 'Ready' is displayed
|
||||||
bool isStartPhase() const {return m_phase<GO_PHASE;}
|
READY_PHASE,
|
||||||
bool isRacePhase() const {return m_phase>=GO_PHASE && m_phase<LIMBO_PHASE;}
|
// 'Set' is displayed
|
||||||
void restartRace();
|
SET_PHASE,
|
||||||
void disableRace(); // Put race into limbo phase
|
// 'Go' is displayed, but this is already race phase
|
||||||
|
GO_PHASE,
|
||||||
PlayerKart *getPlayerKart(int player) const { return m_player_karts[player]; }
|
// the actual race has started, no ready/set/go is displayed anymore
|
||||||
unsigned int getCurrentNumLocalPlayers() const {return m_local_player_karts.size();}
|
RACE_PHASE,
|
||||||
PlayerKart *getLocalPlayerKart(int n) const { return m_local_player_karts[n]; }
|
// All players have finished, now wait a certain amount of time for AI
|
||||||
NetworkKart*getNetworkKart(int n) const {return m_network_karts[n]; }
|
// karts to finish. If they do not finish in that time, finish the race
|
||||||
Kart *getKart(int kartId) const { assert(kartId >= 0 &&
|
DELAY_FINISH_PHASE,
|
||||||
kartId < int(m_kart.size()));
|
// The player crossed the finishing line and his and the time of
|
||||||
return m_kart[kartId]; }
|
// the other players is displayed, controll is automatic
|
||||||
unsigned int getCurrentNumKarts() const { return (int)m_kart.size()-
|
FINISH_PHASE,
|
||||||
m_eliminated_karts; }
|
// The state after finish where no calculations are done.
|
||||||
unsigned int getCurrentNumPlayers() const { return (int)m_player_karts.size()-
|
LIMBO_PHASE,
|
||||||
m_eliminated_players; }
|
};
|
||||||
|
|
||||||
/** Returns the phase of the game */
|
|
||||||
Phase getPhase() const { return m_phase; }
|
|
||||||
Physics *getPhysics() const { return m_physics; }
|
|
||||||
Track *getTrack() const { return m_track; }
|
|
||||||
Kart* getFastestKart() const { return m_fastest_kart; }
|
|
||||||
float getFastestLapTime() const { return m_fastest_lap; }
|
|
||||||
void setFastestLap(Kart *k, float time) {m_fastest_kart=k;m_fastest_lap=time;}
|
|
||||||
const Highscores* getHighscores() const { return m_highscores; }
|
|
||||||
float getTime() const { return m_clock; }
|
|
||||||
|
|
||||||
void pause();
|
|
||||||
void unpause();
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that manages the clock (countdown, chrono, etc.) Also manages stuff
|
||||||
|
* like the 'ready/set/go' text at the beginning or the delay at the end of a race.
|
||||||
|
*/
|
||||||
|
class Clock
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
|
SFXBase *m_prestart_sound;
|
||||||
|
SFXBase *m_start_sound;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elasped/remaining time in seconds
|
||||||
|
*/
|
||||||
|
float m_time;
|
||||||
|
ClockType m_mode;
|
||||||
|
/**
|
||||||
|
* This object will be called to notify it of time events. Currently,
|
||||||
|
* this is only relevant for countdown mode.
|
||||||
|
*/
|
||||||
|
ClockListener* m_listener;
|
||||||
|
|
||||||
|
|
||||||
|
Phase m_phase;
|
||||||
|
/**
|
||||||
|
* Counts time during the initial 'ready/set/go' phase, or at the end of a race.
|
||||||
|
* This timer basically kicks in when we need to calculate non-race time like labels.
|
||||||
|
*/
|
||||||
|
float m_auxiliary_timer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remember previous phase e.g. on pause
|
||||||
|
*/
|
||||||
|
Phase m_previous_phase;
|
||||||
|
public:
|
||||||
|
Clock();
|
||||||
|
~Clock();
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
// Note: GO_PHASE is both: start phase and race phase
|
||||||
|
bool isStartPhase() const { return m_phase<GO_PHASE; }
|
||||||
|
bool isRacePhase() const { return m_phase>=GO_PHASE && m_phase<LIMBO_PHASE; }
|
||||||
|
const Phase getPhase() const { return m_phase; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call to specify what kind of clock you want. The second argument
|
||||||
|
* can be used to specify the initial time value (especially useful
|
||||||
|
* for countdowns)
|
||||||
|
*/
|
||||||
|
void setMode(const ClockType mode, const float initial_time=0.0f);
|
||||||
|
int getMode() const { return m_mode; }
|
||||||
|
/**
|
||||||
|
* Call each frame, with the elapsed time as argument.
|
||||||
|
*/
|
||||||
|
void updateClock(const float dt);
|
||||||
|
|
||||||
|
float getTime() const { return m_time; }
|
||||||
|
void setTime(const float time);
|
||||||
|
|
||||||
|
void pause();
|
||||||
|
void unpause();
|
||||||
|
|
||||||
|
void raceOver(const bool delay=false);
|
||||||
|
|
||||||
|
void registerEventListener(ClockListener* listener);
|
||||||
|
};
|
||||||
|
|
||||||
|
class World
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef std::vector<Kart*> Karts;
|
||||||
|
|
||||||
std::vector<PlayerKart*> m_player_karts;
|
std::vector<PlayerKart*> m_player_karts;
|
||||||
std::vector<PlayerKart*> m_local_player_karts;
|
std::vector<PlayerKart*> m_local_player_karts;
|
||||||
std::vector<NetworkKart*> m_network_karts;
|
std::vector<NetworkKart*> m_network_karts;
|
||||||
RandomGenerator m_random;
|
RandomGenerator m_random;
|
||||||
|
|
||||||
|
Clock m_clock;
|
||||||
Karts m_kart;
|
Karts m_kart;
|
||||||
Physics* m_physics;
|
Physics* m_physics;
|
||||||
float m_fastest_lap;
|
float m_fastest_lap;
|
||||||
Kart* m_fastest_kart;
|
Kart* m_fastest_kart;
|
||||||
Highscores* m_highscores;
|
Highscores* m_highscores;
|
||||||
Phase m_phase;
|
|
||||||
Phase m_previous_phase; // used during the race popup menu
|
Phase m_previous_phase; // used during the race popup menu
|
||||||
float m_clock;
|
|
||||||
float m_finish_delay_start_time;
|
|
||||||
int m_eliminated_karts; // number of eliminated karts
|
int m_eliminated_karts; // number of eliminated karts
|
||||||
int m_eliminated_players; // number of eliminated players
|
int m_eliminated_players; // number of eliminated players
|
||||||
std::vector<float>
|
|
||||||
m_leader_intervals; // time till elimination in follow leader
|
|
||||||
bool m_faster_music_active; // true if faster music was activated
|
bool m_faster_music_active; // true if faster music was activated
|
||||||
SFXBase *m_prestart_sound;
|
|
||||||
SFXBase *m_start_sound;
|
|
||||||
|
|
||||||
void updateRacePosition(int k);
|
void updateRacePosition(int k);
|
||||||
void updateHighscores ();
|
void updateHighscores ();
|
||||||
void loadTrack ();
|
void loadTrack ();
|
||||||
void updateRaceStatus (float dt);
|
|
||||||
void resetAllKarts ();
|
void resetAllKarts ();
|
||||||
void removeKart (int kart_number);
|
void removeKart (int kart_number);
|
||||||
Kart* loadRobot (const std::string& kart_name, int position,
|
Kart* loadRobot (const std::string& kart_name, int position,
|
||||||
const btTransform& init_pos);
|
const btTransform& init_pos);
|
||||||
void updateLeaderMode (float dt);
|
|
||||||
void printProfileResultAndExit();
|
void printProfileResultAndExit();
|
||||||
void estimateFinishTimes();
|
void estimateFinishTimes();
|
||||||
#ifdef HAVE_GHOST_REPLAY
|
|
||||||
private:
|
public:
|
||||||
bool saveReplayHumanReadable( std::string const &filename ) const;
|
Track* m_track;
|
||||||
bool loadReplayHumanReadable( std::string const &filename );
|
|
||||||
|
/** debug text that will be overlaid to the screen */
|
||||||
ReplayRecorder m_replay_recorder;
|
std::string m_debug_text[10];
|
||||||
ReplayPlayer *m_p_replay_player;
|
|
||||||
#endif
|
World();
|
||||||
|
virtual ~World();
|
||||||
|
virtual void update(float delta);
|
||||||
|
virtual void restartRace();
|
||||||
|
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]; }
|
||||||
|
unsigned int getCurrentNumKarts() const { return (int)m_kart.size() -
|
||||||
|
m_eliminated_karts; }
|
||||||
|
unsigned int getCurrentNumPlayers() const { return (int)m_player_karts.size()-
|
||||||
|
m_eliminated_players; }
|
||||||
|
|
||||||
|
Physics *getPhysics() const { return m_physics; }
|
||||||
|
Track *getTrack() const { return m_track; }
|
||||||
|
Kart* getFastestKart() const { return m_fastest_kart; }
|
||||||
|
float getFastestLapTime() const { return m_fastest_lap; }
|
||||||
|
void setFastestLap(Kart *k, float time) {m_fastest_kart=k;m_fastest_lap=time; }
|
||||||
|
const Highscores* getHighscores() const { return m_highscores; }
|
||||||
|
float getTime() const { return m_clock.getTime(); }
|
||||||
|
Phase getPhase() const { return m_clock.getPhase(); }
|
||||||
|
const Clock& getClock() const { return m_clock; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when race is over and should be terminated (mostly called by the clock).
|
||||||
|
*/
|
||||||
|
void terminateRace();
|
||||||
|
|
||||||
|
void pause();
|
||||||
|
void unpause();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The code that draws the timer should call this first to know
|
||||||
|
* whether the game mode wants a timer drawn
|
||||||
|
*/
|
||||||
|
bool shouldDrawTimer() const { return ((m_clock.getPhase() == RACE_PHASE or
|
||||||
|
m_clock.getPhase() == DELAY_FINISH_PHASE) and
|
||||||
|
m_clock.getMode() != CLOCK_NONE); }
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user