2007-05-27 12:01:53 -04:00
|
|
|
// $Id$
|
|
|
|
//
|
|
|
|
// 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
|
2008-06-12 20:53:52 -04:00
|
|
|
// as published by the Free Software Foundation; either version 3
|
2007-05-27 12:01:53 -04:00
|
|
|
// 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.
|
|
|
|
|
2009-06-02 21:36:48 -04:00
|
|
|
#include "modes/world.hpp"
|
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
#include <assert.h>
|
|
|
|
#include <sstream>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <ctime>
|
|
|
|
|
2008-11-06 23:34:01 -05:00
|
|
|
#include "audio/sound_manager.hpp"
|
|
|
|
#include "audio/sfx_manager.hpp"
|
|
|
|
#include "audio/sfx_base.hpp"
|
2009-01-22 17:27:13 -05:00
|
|
|
#include "challenges/unlock_manager.hpp"
|
2009-06-11 06:00:43 -04:00
|
|
|
#include "config/user_config.hpp"
|
2009-01-23 00:23:22 -05:00
|
|
|
#include "graphics/camera.hpp"
|
2009-01-22 17:27:13 -05:00
|
|
|
#include "graphics/scene.hpp"
|
2009-07-18 13:48:36 -04:00
|
|
|
#include "states_screens/state_manager.hpp"
|
|
|
|
#include "states_screens/race_gui.hpp"
|
2009-03-11 23:49:31 -04:00
|
|
|
#include "io/file_manager.hpp"
|
2008-11-06 23:34:01 -05:00
|
|
|
#include "items/item_manager.hpp"
|
|
|
|
#include "items/projectile_manager.hpp"
|
|
|
|
#include "karts/auto_kart.hpp"
|
|
|
|
#include "karts/player_kart.hpp"
|
|
|
|
#include "karts/kart_properties_manager.hpp"
|
2008-09-07 09:51:44 -04:00
|
|
|
#include "network/network_manager.hpp"
|
2008-09-07 10:42:37 -04:00
|
|
|
#include "network/race_state.hpp"
|
2009-06-02 21:36:48 -04:00
|
|
|
#include "race/highscore_manager.hpp"
|
|
|
|
#include "race/history.hpp"
|
|
|
|
#include "race/race_manager.hpp"
|
2008-11-06 23:34:01 -05:00
|
|
|
#include "robots/default_robot.hpp"
|
2009-01-22 17:27:13 -05:00
|
|
|
#include "tracks/track.hpp"
|
2009-01-22 07:02:40 -05:00
|
|
|
#include "tracks/track_manager.hpp"
|
2009-01-22 17:27:13 -05:00
|
|
|
#include "utils/constants.hpp"
|
2009-01-23 00:23:22 -05:00
|
|
|
#include "utils/translation.hpp"
|
2009-01-27 19:38:28 -05:00
|
|
|
#include "utils/string_utils.hpp"
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2008-09-20 19:45:22 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2008-10-04 13:32:40 -04:00
|
|
|
World::World() : TimedRace()
|
2008-11-07 21:07:54 -05:00
|
|
|
{
|
2009-07-12 07:54:21 -04:00
|
|
|
m_physics = NULL;
|
|
|
|
m_race_gui = NULL;
|
|
|
|
} // World
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2008-11-07 21:07:54 -05:00
|
|
|
void World::init()
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2008-09-21 12:07:56 -04:00
|
|
|
RaceManager::setWorld(this);
|
2008-09-07 10:42:37 -04:00
|
|
|
race_state = new RaceState();
|
2008-05-07 21:28:07 -04:00
|
|
|
m_track = NULL;
|
|
|
|
m_faster_music_active = false;
|
|
|
|
m_fastest_lap = 9999999.9f;
|
|
|
|
m_fastest_kart = 0;
|
|
|
|
m_eliminated_karts = 0;
|
|
|
|
m_eliminated_players = 0;
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2008-10-04 14:50:45 -04:00
|
|
|
TimedRace::setClockMode( CHRONO );
|
2008-09-23 20:13:31 -04:00
|
|
|
m_use_highscores = true;
|
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
// Grab the track file
|
|
|
|
try
|
|
|
|
{
|
1) Removed race_setup and race_mode data structures. All this
information is now only managed by the race_manager, no
more in-between objects to transfer information along.
2) The scores for grand prix are now defined in the stk_config.dat
file (10, 8, 6, 5, 4, .., 1, 0, 0) points
3) Bugfix: unlock information wasn't saved anymore. Added specific
saving after unlocking, plus re-inserted the 'generic' save
at the end of STK again.
4) bugfix/work around: Visual Studio complains about incompatible
iterators in sdldrv - apparently caused by using erase, and
then keep on using the iterator.
5) Fixed bug when running a race in a GP again (scores/times
were added each time).
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1681 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2008-04-09 09:52:48 -04:00
|
|
|
m_track = track_manager->getTrack(race_manager->getTrackName());
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
|
|
|
catch(std::runtime_error)
|
|
|
|
{
|
2009-01-23 00:23:22 -05:00
|
|
|
std::ostringstream msg;
|
|
|
|
msg << "Track '" << race_manager->getTrackName() << "' not found.\n";
|
|
|
|
throw std::runtime_error(msg.str());
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create the physics
|
2008-09-19 02:07:29 -04:00
|
|
|
m_physics = new Physics();
|
2007-05-27 12:01:53 -04:00
|
|
|
|
1) Removed race_setup and race_mode data structures. All this
information is now only managed by the race_manager, no
more in-between objects to transfer information along.
2) The scores for grand prix are now defined in the stk_config.dat
file (10, 8, 6, 5, 4, .., 1, 0, 0) points
3) Bugfix: unlock information wasn't saved anymore. Added specific
saving after unlocking, plus re-inserted the 'generic' save
at the end of STK again.
4) bugfix/work around: Visual Studio complains about incompatible
iterators in sdldrv - apparently caused by using erase, and
then keep on using the iterator.
5) Fixed bug when running a race in a GP again (scores/times
were added each time).
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1681 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2008-04-09 09:52:48 -04:00
|
|
|
assert(race_manager->getNumKarts() > 0);
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
// Load the track models - this must be done before the karts so that the
|
|
|
|
// karts can be positioned properly on (and not in) the tracks.
|
2007-12-12 09:07:26 -05:00
|
|
|
loadTrack() ;
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2008-07-14 01:21:37 -04:00
|
|
|
m_player_karts.resize(race_manager->getNumPlayers());
|
2008-09-07 10:34:04 -04:00
|
|
|
m_network_karts.resize(race_manager->getNumPlayers());
|
2008-09-07 09:33:12 -04:00
|
|
|
m_local_player_karts.resize(race_manager->getNumLocalPlayers());
|
2008-07-14 01:21:37 -04:00
|
|
|
|
2008-04-16 20:20:06 -04:00
|
|
|
for(unsigned int i=0; i<race_manager->getNumKarts(); i++)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2008-04-16 20:20:06 -04:00
|
|
|
int position = i+1; // position start with 1
|
2008-10-14 16:20:54 -04:00
|
|
|
btTransform init_pos=m_track->getStartTransform(i);
|
2007-05-27 12:01:53 -04:00
|
|
|
Kart* newkart;
|
2008-09-07 09:51:44 -04:00
|
|
|
const std::string& kart_name = race_manager->getKartName(i);
|
|
|
|
int local_player_id = race_manager->getKartLocalPlayerId(i);
|
|
|
|
int global_player_id = race_manager->getKartGlobalPlayerId(i);
|
2009-06-20 21:10:43 -04:00
|
|
|
if(UserConfigParams::m_profile)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
|
|
|
// In profile mode, load only the old kart
|
2008-12-07 20:29:02 -05:00
|
|
|
newkart = new DefaultRobot(kart_name, position, init_pos, m_track);
|
2008-09-21 12:07:56 -04:00
|
|
|
// Create a camera for the last kart (since this way more of the
|
|
|
|
// karts can be seen.
|
2008-04-16 20:20:06 -04:00
|
|
|
if(i==race_manager->getNumKarts()-1)
|
2008-02-17 07:58:12 -05:00
|
|
|
{
|
2009-01-27 19:38:28 -05:00
|
|
|
stk_scene->createCamera(local_player_id, newkart);
|
2008-12-09 00:05:48 -05:00
|
|
|
m_local_player_karts[0] = static_cast<PlayerKart*>(newkart);
|
2008-02-17 07:58:12 -05:00
|
|
|
}
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-09-07 09:25:58 -04:00
|
|
|
switch(race_manager->getKartType(i))
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2008-09-07 09:25:58 -04:00
|
|
|
case RaceManager::KT_PLAYER:
|
2009-07-18 11:21:16 -04:00
|
|
|
std::cout << "===== World : creating player kart for kart #" << i << " which has local_player_id " << local_player_id << " ===========\n";
|
1) Removed race_setup and race_mode data structures. All this
information is now only managed by the race_manager, no
more in-between objects to transfer information along.
2) The scores for grand prix are now defined in the stk_config.dat
file (10, 8, 6, 5, 4, .., 1, 0, 0) points
3) Bugfix: unlock information wasn't saved anymore. Added specific
saving after unlocking, plus re-inserted the 'generic' save
at the end of STK again.
4) bugfix/work around: Visual Studio complains about incompatible
iterators in sdldrv - apparently caused by using erase, and
then keep on using the iterator.
5) Fixed bug when running a race in a GP again (scores/times
were added each time).
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1681 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2008-04-09 09:52:48 -04:00
|
|
|
newkart = new PlayerKart(kart_name, position,
|
2009-07-18 13:48:36 -04:00
|
|
|
StateManager::get()->getActivePlayer(local_player_id),
|
2008-09-07 09:51:44 -04:00
|
|
|
init_pos, local_player_id);
|
|
|
|
m_player_karts[global_player_id] = (PlayerKart*)newkart;
|
|
|
|
m_local_player_karts[local_player_id] = static_cast<PlayerKart*>(newkart);
|
2008-09-07 09:25:58 -04:00
|
|
|
break;
|
|
|
|
case RaceManager::KT_NETWORK_PLAYER:
|
2008-09-07 10:42:37 -04:00
|
|
|
newkart = new NetworkKart(kart_name, position, init_pos,
|
|
|
|
global_player_id);
|
2008-09-07 10:34:04 -04:00
|
|
|
m_network_karts[global_player_id] = static_cast<NetworkKart*>(newkart);
|
2008-09-19 10:14:14 -04:00
|
|
|
m_player_karts[global_player_id] = (PlayerKart*)newkart;
|
2008-09-07 09:25:58 -04:00
|
|
|
break;
|
|
|
|
case RaceManager::KT_AI:
|
2009-07-11 20:18:37 -04:00
|
|
|
std::cout << "===== World : creating AI kart for #" << i << "===========\n";
|
|
|
|
|
1) Removed race_setup and race_mode data structures. All this
information is now only managed by the race_manager, no
more in-between objects to transfer information along.
2) The scores for grand prix are now defined in the stk_config.dat
file (10, 8, 6, 5, 4, .., 1, 0, 0) points
3) Bugfix: unlock information wasn't saved anymore. Added specific
saving after unlocking, plus re-inserted the 'generic' save
at the end of STK again.
4) bugfix/work around: Visual Studio complains about incompatible
iterators in sdldrv - apparently caused by using erase, and
then keep on using the iterator.
5) Fixed bug when running a race in a GP again (scores/times
were added each time).
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1681 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2008-04-09 09:52:48 -04:00
|
|
|
newkart = loadRobot(kart_name, position, init_pos);
|
2008-09-07 09:25:58 -04:00
|
|
|
break;
|
|
|
|
case RaceManager::KT_GHOST:
|
|
|
|
break;
|
2008-09-07 10:09:52 -04:00
|
|
|
case RaceManager::KT_LEADER:
|
|
|
|
break;
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
2009-06-20 21:10:43 -04:00
|
|
|
} // if !UserConfigParams::m_profile
|
2007-05-27 12:01:53 -04:00
|
|
|
m_kart.push_back(newkart);
|
2008-09-07 10:42:37 -04:00
|
|
|
newkart->setWorldKartId(m_kart.size()-1);
|
2007-05-27 12:01:53 -04:00
|
|
|
} // for i
|
|
|
|
|
|
|
|
resetAllKarts();
|
2009-07-06 09:35:33 -04:00
|
|
|
// Note: track reset must be called after all karts exist, since check
|
|
|
|
// objects need to allocate data structures depending on the number
|
|
|
|
// of karts.
|
|
|
|
m_track->reset();
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2009-07-12 07:54:21 -04:00
|
|
|
m_race_gui = new RaceGUI();
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2008-05-07 21:28:07 -04:00
|
|
|
m_track->startMusic();
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2008-10-06 09:40:11 -04:00
|
|
|
if(!history->replayHistory()) history->initRecording();
|
2008-09-07 10:09:52 -04:00
|
|
|
network_manager->worldLoaded();
|
2007-12-08 08:04:56 -05:00
|
|
|
} // World
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
World::~World()
|
|
|
|
{
|
2009-07-12 07:54:21 -04:00
|
|
|
delete m_race_gui;
|
|
|
|
|
2008-11-11 17:21:25 -05:00
|
|
|
item_manager->cleanup();
|
2008-09-07 10:42:37 -04:00
|
|
|
delete race_state;
|
2009-01-15 18:05:50 -05:00
|
|
|
// In case that a race is aborted (e.g. track not found) m_track is 0.
|
|
|
|
if(m_track)
|
|
|
|
m_track->cleanup();
|
2007-12-08 08:04:56 -05:00
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
for ( unsigned int i = 0 ; i < m_kart.size() ; i++ )
|
|
|
|
delete m_kart[i];
|
|
|
|
|
|
|
|
m_kart.clear();
|
|
|
|
projectile_manager->cleanup();
|
2009-01-15 18:05:50 -05:00
|
|
|
// In case that the track is not found, m_physics is still undefined.
|
|
|
|
if(m_physics)
|
|
|
|
delete m_physics;
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
sound_manager -> stopMusic();
|
2007-11-03 09:13:26 -04:00
|
|
|
} // ~World
|
2009-07-12 07:54:21 -04:00
|
|
|
|
2008-09-20 19:45:22 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void World::terminateRace()
|
|
|
|
{
|
2008-09-22 21:16:50 -04:00
|
|
|
updateHighscores();
|
2008-10-04 13:32:40 -04:00
|
|
|
TimedRace::pause();
|
2009-03-13 09:50:24 -04:00
|
|
|
// TODO - race results GUI
|
|
|
|
//menu_manager->pushMenu(MENUID_RACERESULT);
|
2008-09-20 19:45:22 -04:00
|
|
|
unlock_manager->raceFinished();
|
|
|
|
}
|
2007-05-27 12:01:53 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** Waits till each kart is resting on the ground
|
|
|
|
*
|
|
|
|
* Does simulation steps still all karts reach the ground, i.e. are not
|
|
|
|
* moving anymore
|
|
|
|
*/
|
|
|
|
void World::resetAllKarts()
|
|
|
|
{
|
|
|
|
bool all_finished=false;
|
2008-02-12 22:42:18 -05:00
|
|
|
// kart->isInRest() is not fully correct, since it only takes the
|
|
|
|
// velocity in count, which might be close to zero when the kart
|
|
|
|
// is just hitting the floor, before being pushed up again by
|
|
|
|
// the suspension. So we just do a longer initial simulation,
|
|
|
|
// which should be long enough for all karts to be firmly on ground.
|
2008-07-09 20:41:26 -04:00
|
|
|
for(int i=0; i<200; i++) m_physics->update(1.f/60.f);
|
|
|
|
|
|
|
|
// Stil wait will all karts are in rest (and handle the case that a kart
|
|
|
|
// fell through the ground, which can happen if a kart falls for a long
|
|
|
|
// time, therefore having a high speed when hitting the ground.
|
2007-05-27 12:01:53 -04:00
|
|
|
while(!all_finished)
|
|
|
|
{
|
2007-11-21 20:20:57 -05:00
|
|
|
m_physics->update(1.f/60.f);
|
2007-05-27 12:01:53 -04:00
|
|
|
all_finished=true;
|
|
|
|
for ( Karts::iterator i=m_kart.begin(); i!=m_kart.end(); i++)
|
|
|
|
{
|
|
|
|
if(!(*i)->isInRest())
|
|
|
|
{
|
2008-07-09 20:41:26 -04:00
|
|
|
float hot;
|
|
|
|
Vec3 normal;
|
|
|
|
const Material *material;
|
|
|
|
// We can't use (*i)->getXYZ(), since this is only defined
|
|
|
|
// after update() was called. Instead we have to get the
|
|
|
|
// real position of the rigid body.
|
|
|
|
btTransform t;
|
|
|
|
(*i)->getBody()->getMotionState()->getWorldTransform(t);
|
|
|
|
// This test can not be done only once before the loop, since
|
|
|
|
// it can happen that the kart falls through the track later!
|
|
|
|
m_track->getTerrainInfo(t.getOrigin(), &hot, &normal, &material);
|
|
|
|
if(!material)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "ERROR: no valid starting position for kart %d on track %s.\n",
|
2008-09-21 12:07:56 -04:00
|
|
|
(int)(i-m_kart.begin()), m_track->getIdent().c_str());
|
2008-07-09 20:41:26 -04:00
|
|
|
exit(-1);
|
|
|
|
}
|
2007-05-27 12:01:53 -04:00
|
|
|
all_finished=false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // while
|
2008-01-29 23:36:00 -05:00
|
|
|
|
2008-11-06 20:05:52 -05:00
|
|
|
// Now store the current (i.e. in rest) suspension length for each kart,
|
|
|
|
// so that the karts can visualise the suspension.
|
|
|
|
for ( Karts::iterator i=m_kart.begin(); i!=m_kart.end(); i++)
|
|
|
|
(*i)->setSuspensionLength();
|
2009-02-01 17:54:00 -05:00
|
|
|
for(unsigned int i=0; i<m_player_karts.size(); i++)
|
|
|
|
m_player_karts[i]->getCamera()->setInitialTransform();
|
2007-05-27 12:01:53 -04:00
|
|
|
} // resetAllKarts
|
|
|
|
|
2009-07-12 07:54:21 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** Called during rendering. In this function direct calls to the graphics
|
|
|
|
* are possible, e.g. using an irrlicht font object to directly print to
|
|
|
|
* the screen, ...
|
|
|
|
*/
|
|
|
|
void World::render()
|
|
|
|
{
|
|
|
|
m_race_gui->render();
|
|
|
|
} // render
|
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2007-12-12 09:07:26 -05:00
|
|
|
void World::update(float dt)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2008-10-06 09:40:11 -04:00
|
|
|
if(history->replayHistory()) dt=history->getNextDelta();
|
2008-10-04 13:32:40 -04:00
|
|
|
TimedRace::update(dt);
|
2008-09-07 10:42:37 -04:00
|
|
|
// Clear race state so that new information can be stored
|
|
|
|
race_state->clear();
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2009-03-31 19:45:20 -04:00
|
|
|
m_track->update(dt);
|
2008-10-06 09:40:11 -04:00
|
|
|
if(network_manager->getMode()!=NetworkManager::NW_CLIENT &&
|
|
|
|
!history->dontDoPhysics())
|
|
|
|
{
|
|
|
|
m_physics->update(dt);
|
|
|
|
}
|
|
|
|
|
2008-09-23 20:43:45 -04:00
|
|
|
const int kart_amount = m_kart.size();
|
|
|
|
for (int i = 0 ; i < kart_amount; ++i)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2008-04-15 09:57:18 -04:00
|
|
|
// Update all karts that are not eliminated
|
2008-07-14 23:33:17 -04:00
|
|
|
if(!m_kart[i]->isEliminated()) m_kart[i]->update(dt) ;
|
2007-12-12 09:07:26 -05:00
|
|
|
}
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2007-12-12 09:07:26 -05:00
|
|
|
projectile_manager->update(dt);
|
2008-10-29 11:55:54 -04:00
|
|
|
item_manager->update(dt);
|
2009-07-12 07:54:21 -04:00
|
|
|
m_race_gui->update(dt);
|
2009-03-31 20:55:20 -04:00
|
|
|
} // update
|
|
|
|
|
2008-05-19 23:33:48 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-09-28 22:29:33 -04:00
|
|
|
|
2008-09-22 21:16:50 -04:00
|
|
|
HighscoreEntry* World::getHighscores() const
|
|
|
|
{
|
2008-09-23 20:13:31 -04:00
|
|
|
if(!m_use_highscores) return NULL;
|
|
|
|
|
2008-09-22 21:16:50 -04:00
|
|
|
const HighscoreEntry::HighscoreType type = "HST_" + getInternalCode();
|
|
|
|
|
|
|
|
HighscoreEntry* highscores =
|
|
|
|
highscore_manager->getHighscoreEntry(type,
|
|
|
|
race_manager->getNumKarts(),
|
|
|
|
race_manager->getDifficulty(),
|
|
|
|
race_manager->getTrackName(),
|
|
|
|
race_manager->getNumLaps());
|
|
|
|
|
|
|
|
return highscores;
|
|
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
* usually called at the end of a race. Checks if the current times are worth a new
|
|
|
|
* score, if so it notifies the HighscoreManager so the new score is added and saved.
|
|
|
|
*/
|
2008-05-19 23:33:48 -04:00
|
|
|
void World::updateHighscores()
|
|
|
|
{
|
2008-09-23 20:13:31 -04:00
|
|
|
if(!m_use_highscores) return;
|
|
|
|
|
2008-05-19 23:33:48 -04:00
|
|
|
// Add times to highscore list. First compute the order of karts,
|
|
|
|
// so that the timing of the fastest kart is added first (otherwise
|
|
|
|
// someone might get into the highscore list, only to be kicked out
|
|
|
|
// 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()];
|
2008-09-29 11:27:09 -04:00
|
|
|
|
2008-09-28 22:29:33 -04:00
|
|
|
const unsigned int kart_amount = m_kart.size();
|
2008-09-23 20:43:45 -04:00
|
|
|
for (unsigned int i=0; i<kart_amount; i++ )
|
2008-05-19 23:33:48 -04:00
|
|
|
{
|
2008-09-29 11:27:09 -04:00
|
|
|
index[i] = 999; // first reset the contents of the array
|
2008-10-22 12:05:08 -04:00
|
|
|
}
|
|
|
|
for (unsigned int i=0; i<kart_amount; i++ )
|
|
|
|
{
|
|
|
|
const int pos = m_kart[i]->getPosition()-1;
|
2008-10-24 00:39:52 -04:00
|
|
|
if(pos < 0 || pos >= (int)kart_amount) continue; // wrong position
|
2008-10-22 12:05:08 -04:00
|
|
|
index[pos] = i;
|
2008-05-19 23:33:48 -04:00
|
|
|
}
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2008-09-23 20:43:45 -04:00
|
|
|
for(unsigned int pos=0; pos<kart_amount; pos++)
|
2008-05-19 23:33:48 -04:00
|
|
|
{
|
2008-09-29 21:54:09 -04:00
|
|
|
|
|
|
|
if(index[pos] == 999)
|
2008-07-14 01:21:37 -04:00
|
|
|
{
|
2008-09-29 21:54:09 -04:00
|
|
|
// no kart claimed to be in this position, most likely means
|
|
|
|
// the kart location data is wrong
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
2008-07-14 01:21:37 -04:00
|
|
|
fprintf(stderr, "Error, incorrect kart positions:");
|
|
|
|
for (unsigned int i=0; i<m_kart.size(); i++ )
|
|
|
|
{
|
|
|
|
fprintf(stderr, "i=%d position %d\n",i, m_kart[i]->getPosition());
|
|
|
|
}
|
|
|
|
#endif
|
2008-09-29 21:54:09 -04:00
|
|
|
continue;
|
|
|
|
}
|
2008-09-29 11:23:54 -04:00
|
|
|
|
2008-10-21 12:04:54 -04:00
|
|
|
// Only record times for player karts and only if they finished the race
|
|
|
|
if(!m_kart[index[pos]]->isPlayerKart()) continue;
|
|
|
|
if (!m_kart[index[pos]]->hasFinishedRace()) continue;
|
2008-05-19 23:33:48 -04:00
|
|
|
|
2008-10-22 12:05:08 -04:00
|
|
|
assert(index[pos] >= 0);
|
|
|
|
assert(index[pos] < m_kart.size());
|
2008-05-19 23:33:48 -04:00
|
|
|
PlayerKart *k = (PlayerKart*)m_kart[index[pos]];
|
|
|
|
|
2008-09-22 21:16:50 -04:00
|
|
|
HighscoreEntry* highscores = getHighscores();
|
|
|
|
|
|
|
|
if(highscores->addData(k->getName(),
|
2009-07-18 11:32:54 -04:00
|
|
|
k->getPlayer()->getProfile()->getName(),
|
2008-09-22 21:16:50 -04:00
|
|
|
k->getFinishTime())>0 )
|
2008-05-19 23:33:48 -04:00
|
|
|
{
|
|
|
|
highscore_manager->Save();
|
|
|
|
}
|
2008-09-29 11:43:58 -04:00
|
|
|
} // next position
|
2008-05-19 23:33:48 -04:00
|
|
|
delete []index;
|
2008-09-29 11:43:58 -04:00
|
|
|
|
2008-05-19 23:33:48 -04:00
|
|
|
} // updateHighscores
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void World::printProfileResultAndExit()
|
|
|
|
{
|
|
|
|
float min_t=999999.9f, max_t=0.0, av_t=0.0;
|
|
|
|
for ( Karts::size_type i = 0; i < m_kart.size(); ++i)
|
|
|
|
{
|
|
|
|
max_t = std::max(max_t, m_kart[i]->getFinishTime());
|
|
|
|
min_t = std::min(min_t, m_kart[i]->getFinishTime());
|
|
|
|
av_t += m_kart[i]->getFinishTime();
|
|
|
|
printf("%s start %d end %d time %f\n",
|
|
|
|
m_kart[i]->getName().c_str(),(int)i,
|
|
|
|
m_kart[i]->getPosition(),
|
|
|
|
m_kart[i]->getFinishTime());
|
|
|
|
}
|
|
|
|
printf("min %f max %f av %f\n",min_t, max_t, av_t/m_kart.size());
|
|
|
|
std::exit(-2);
|
|
|
|
} // printProfileResultAndExit
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2008-04-15 09:57:18 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** Called in follow-leader-mode to remove the last kart
|
|
|
|
*/
|
|
|
|
void World::removeKart(int kart_number)
|
|
|
|
{
|
|
|
|
Kart *kart = m_kart[kart_number];
|
2009-07-12 07:54:21 -04:00
|
|
|
|
2008-04-15 09:57:18 -04:00
|
|
|
// Display a message about the eliminated kart in the race gui
|
2009-07-12 07:54:21 -04:00
|
|
|
for (std::vector<PlayerKart*>::iterator i = m_player_karts.begin();
|
|
|
|
i != m_player_karts.end(); i++ )
|
|
|
|
{
|
|
|
|
if(*i==kart)
|
|
|
|
{
|
|
|
|
m_race_gui->addMessage(_("You have been\neliminated!"), *i, 2.0f, 60);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::string s = _("'%s' has\nbeen eliminated.");
|
|
|
|
m_race_gui->addMessage( StringUtils::insert_values(s, kart->getName()),
|
|
|
|
*i, 2.0f, 60);
|
|
|
|
}
|
|
|
|
} // for i in kart
|
2008-04-15 09:57:18 -04:00
|
|
|
if(kart->isPlayerKart())
|
|
|
|
{
|
|
|
|
// Change the camera so that it will be attached to the leader
|
|
|
|
// and facing backwards.
|
|
|
|
Camera* camera=((PlayerKart*)kart)->getCamera();
|
|
|
|
camera->setMode(Camera::CM_LEADER_MODE);
|
|
|
|
m_eliminated_players++;
|
|
|
|
}
|
2008-06-20 05:34:35 -04:00
|
|
|
projectile_manager->newExplosion(kart->getXYZ());
|
2008-04-16 20:20:06 -04:00
|
|
|
// The kart can't be really removed from the m_kart array, since otherwise
|
|
|
|
// a race can't be restarted. So it's only marked to be eliminated (and
|
|
|
|
// ignored in all loops). Important:world->getCurrentNumKarts() returns
|
|
|
|
// the number of karts still racing. This value can not be used for loops
|
|
|
|
// over all karts, use race_manager->getNumKarts() instead!
|
2008-10-04 13:32:40 -04:00
|
|
|
race_manager->RaceFinished(kart, TimedRace::getTime());
|
2008-04-15 09:57:18 -04:00
|
|
|
kart->eliminate();
|
|
|
|
m_eliminated_karts++;
|
|
|
|
|
|
|
|
} // removeKart
|
2007-05-27 12:01:53 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2008-10-29 11:55:54 -04:00
|
|
|
/** Cleans up old items (from a previous race), removes old track specific
|
|
|
|
* item models, and loads the actual track.
|
2008-09-19 02:07:29 -04:00
|
|
|
*/
|
2007-05-27 12:01:53 -04:00
|
|
|
void World::loadTrack()
|
|
|
|
{
|
2008-10-29 11:55:54 -04:00
|
|
|
// remove old items (from previous race), and remove old
|
|
|
|
// track specific item models
|
|
|
|
item_manager->cleanup();
|
2008-09-21 20:55:27 -04:00
|
|
|
if(race_manager->getMajorMode()== RaceManager::MAJOR_MODE_GRAND_PRIX)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2008-10-29 11:55:54 -04:00
|
|
|
item_manager->loadItemStyle(race_manager->getItemStyle());
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
|
|
|
catch(std::runtime_error)
|
|
|
|
{
|
2008-10-29 11:55:54 -04:00
|
|
|
fprintf(stderr, "The grand prix '%s' contains an invalid item style '%s'.\n",
|
2007-05-27 12:01:53 -04:00
|
|
|
race_manager->getGrandPrix()->getName().c_str(),
|
2008-10-29 11:55:54 -04:00
|
|
|
race_manager->getItemStyle().c_str());
|
2007-05-27 12:01:53 -04:00
|
|
|
fprintf(stderr, "Please fix the file '%s'.\n",
|
|
|
|
race_manager->getGrandPrix()->getFilename().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2008-10-29 11:55:54 -04:00
|
|
|
item_manager->loadItemStyle(m_track->getItemStyle());
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
|
|
|
catch(std::runtime_error)
|
|
|
|
{
|
2008-10-29 11:55:54 -04:00
|
|
|
fprintf(stderr, "The track '%s' contains an invalid item style '%s'.\n",
|
|
|
|
m_track->getName(), m_track->getItemStyle().c_str());
|
2007-05-27 12:01:53 -04:00
|
|
|
fprintf(stderr, "Please fix the file '%s'.\n",
|
|
|
|
m_track->getFilename().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-12 09:07:26 -05:00
|
|
|
m_track->loadTrackModel();
|
2007-05-27 12:01:53 -04:00
|
|
|
} // loadTrack
|
2009-07-16 08:09:15 -04:00
|
|
|
|
2008-09-21 20:55:27 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void World::getDefaultCollectibles(int& collectible_type, int& amount )
|
|
|
|
{
|
2008-10-29 22:02:56 -04:00
|
|
|
collectible_type = POWERUP_NOTHING;
|
2008-09-21 20:55:27 -04:00
|
|
|
amount = 0;
|
|
|
|
}
|
2007-05-27 12:01:53 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void World::restartRace()
|
|
|
|
{
|
2008-10-04 13:32:40 -04:00
|
|
|
TimedRace::reset();
|
2009-06-30 08:51:38 -04:00
|
|
|
m_track->reset();
|
2008-05-07 21:28:07 -04:00
|
|
|
m_faster_music_active = false;
|
|
|
|
m_eliminated_karts = 0;
|
|
|
|
m_eliminated_players = 0;
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
for ( Karts::iterator i = m_kart.begin(); i != m_kart.end() ; ++i )
|
|
|
|
{
|
|
|
|
(*i)->reset();
|
|
|
|
}
|
2008-09-20 19:45:22 -04:00
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
resetAllKarts();
|
2008-09-20 19:45:22 -04:00
|
|
|
|
|
|
|
// Start music from beginning
|
|
|
|
sound_manager->stopMusic();
|
2008-05-07 21:28:07 -04:00
|
|
|
m_track->startMusic();
|
2008-09-20 19:45:22 -04:00
|
|
|
|
2008-09-20 10:23:20 -04:00
|
|
|
// Enable SFX again
|
|
|
|
sfx_manager->resumeAll();
|
2008-09-20 19:45:22 -04:00
|
|
|
|
2008-10-29 11:55:54 -04:00
|
|
|
item_manager->reset();
|
2007-05-27 12:01:53 -04:00
|
|
|
projectile_manager->cleanup();
|
|
|
|
race_manager->reset();
|
2007-09-21 15:17:48 -04:00
|
|
|
|
2008-02-11 19:01:27 -05:00
|
|
|
// Resets the cameras in case that they are pointing too steep up or down
|
2009-01-27 19:38:28 -05:00
|
|
|
stk_scene->reset();
|
2008-02-11 19:01:27 -05:00
|
|
|
} // restartRace
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
1) Removed race_setup and race_mode data structures. All this
information is now only managed by the race_manager, no
more in-between objects to transfer information along.
2) The scores for grand prix are now defined in the stk_config.dat
file (10, 8, 6, 5, 4, .., 1, 0, 0) points
3) Bugfix: unlock information wasn't saved anymore. Added specific
saving after unlocking, plus re-inserted the 'generic' save
at the end of STK again.
4) bugfix/work around: Visual Studio complains about incompatible
iterators in sdldrv - apparently caused by using erase, and
then keep on using the iterator.
5) Fixed bug when running a race in a GP again (scores/times
were added each time).
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1681 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2008-04-09 09:52:48 -04:00
|
|
|
Kart* World::loadRobot(const std::string& kart_name, int position,
|
2008-06-20 05:34:35 -04:00
|
|
|
const btTransform& init_pos)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
|
|
|
Kart* currentRobot;
|
|
|
|
|
|
|
|
const int NUM_ROBOTS = 1;
|
|
|
|
|
2008-09-07 10:34:04 -04:00
|
|
|
switch(m_random.get(NUM_ROBOTS))
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
|
|
|
case 0:
|
2008-12-07 20:29:02 -05:00
|
|
|
currentRobot = new DefaultRobot(kart_name, position, init_pos, m_track);
|
2007-05-27 12:01:53 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
std::cerr << "Warning: Unknown robot, using default." << std::endl;
|
2008-12-07 20:29:02 -05:00
|
|
|
currentRobot = new DefaultRobot(kart_name, position, init_pos, m_track);
|
2007-05-27 12:01:53 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return currentRobot;
|
|
|
|
}
|
|
|
|
|
2007-06-09 21:13:39 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void World::pause()
|
|
|
|
{
|
2008-09-20 10:23:20 -04:00
|
|
|
sound_manager->pauseMusic();
|
|
|
|
sfx_manager->pauseAll();
|
2008-10-04 13:32:40 -04:00
|
|
|
TimedRace::pause();
|
2007-06-09 21:13:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void World::unpause()
|
|
|
|
{
|
2008-09-20 10:23:20 -04:00
|
|
|
sound_manager->resumeMusic() ;
|
|
|
|
sfx_manager->resumeAll();
|
2008-10-04 13:32:40 -04:00
|
|
|
TimedRace::unpause();
|
2009-01-30 23:51:50 -05:00
|
|
|
for(unsigned int i=0; i<m_player_karts.size(); i++)
|
|
|
|
m_player_karts[i]->resetInputState();
|
2007-06-09 21:13:39 -04:00
|
|
|
}
|
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
/* EOF */
|