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
This commit is contained in:
hikerstk 2008-04-09 13:52:48 +00:00
parent b3edac2171
commit 3e6a0cf5ab
44 changed files with 506 additions and 731 deletions

View File

@ -5,6 +5,7 @@
;; STK parameters
;; --------------
(max-karts 10 ) ;; maximum number of karts
(scores 10 8 6 5 4 3 2 1 0 0 )
(grid-order 1 ) ;; order for grand prix, 1 is most
;; points 1st, 0 is least points
;; 1st

View File

@ -27,9 +27,9 @@
class AutoKart : public Kart
{
public:
AutoKart(const KartProperties *kart_properties, int position,
AutoKart(const std::string& kart_name, int position,
sgCoord init_pos) :
Kart(kart_properties, position, init_pos) { Kart::reset(); }
Kart(kart_name, position, init_pos) { Kart::reset(); }
int isPlayerKart() const {return 0;}
};

View File

@ -80,15 +80,15 @@ void Camera::setScreenPosition ( int numPlayers, int pos )
} // setScreenPosition
//-----------------------------------------------------------------------------
Camera::Camera ( int numPlayers, int which_ )
Camera::Camera(int numPlayers, int which)
: m_reverse(false)
{
m_which_kart = which_ ; // Just for now
m_which_kart = which; // Just for now
m_mode = CM_NORMAL;
m_context = new ssgContext ;
// FIXME: clipping should be configurable for slower machines
const Track* track = track_manager->getTrack(world->m_race_setup.m_track);
const Track* track = world->getTrack();
if (track->useFog())
m_context -> setNearFar ( 0.05f, track->getFogEnd() ) ;
else
@ -99,9 +99,9 @@ Camera::Camera ( int numPlayers, int which_ )
} // Camera
//-----------------------------------------------------------------------------
void Camera::setMode(Mode mode_)
void Camera::setMode(Mode mode)
{
m_mode = mode_;
m_mode = mode;
} // setMode
//-----------------------------------------------------------------------------

View File

@ -9,6 +9,7 @@
// as published by the Free Software Foundation; either version 2
// 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
@ -29,6 +30,7 @@ public:
enum Mode {
CM_NORMAL,
CM_CLOSEUP,
CM_LEADER_MODE, // for deleted player karts in follow the leader
//FIXME: NO_FAKE_DRIFT is broken
CM_NO_FAKE_DRIFT,
CM_SIMPLE_REPLAY

View File

@ -20,7 +20,6 @@
#include <algorithm>
#include "challenges/win_gotm_cup.hpp"
#include "world.hpp"
#include "race_setup.hpp"
#include "race_manager.hpp"
WinGOTMCup::WinGOTMCup() : Challenge("wingotmcup", "Win GOTM Cup")
@ -35,11 +34,10 @@ WinGOTMCup::WinGOTMCup() : Challenge("wingotmcup", "Win GOTM Cup")
//-----------------------------------------------------------------------------
bool WinGOTMCup::grandPrixFinished()
{
const RaceSetup* race=&world->m_race_setup;
if (race->m_mode != RaceSetup::RM_GRAND_PRIX ||
race->m_difficulty != RD_HARD ||
race->getNumKarts() < 4 ||
race->getNumPlayers() > 1) return false;
if (race_manager->getRaceMode() != RaceManager::RM_GRAND_PRIX ||
race_manager->getDifficulty()!= RaceManager::RD_HARD ||
race_manager->getNumKarts() < 4 ||
race_manager->getNumPlayers() > 1) return false;
// Check if the player was number one:
for(int i=0; i<(int)world->getNumKarts(); i++)
{

View File

@ -19,6 +19,7 @@
#include "collectable.hpp"
#include "user_config.hpp"
#include "race_manager.hpp"
#include "projectile_manager.hpp"
#include "kart.hpp"
#include "sound_manager.hpp"
@ -170,7 +171,7 @@ void Collectable::hitRedHerring(int n)
// A zipper should not be used during time trial, since it
// brings too much randomness. So ignore the top 3 elements
// in time trail, but only the top 2 in any other mode
int nIgnore = (world->m_race_setup.m_mode == RaceSetup::RM_TIME_TRIAL)
int nIgnore = (race_manager->getRaceMode()== RaceManager::RM_TIME_TRIAL)
? 3 : 2;
newC = (CollectableType)(rand()%(COLLECT_MAX - 1 - nIgnore) + 1);
}

View File

@ -48,13 +48,17 @@ public:
/** Load the CupData from the given filename */
CupData (const std::string filename);
CupData () {}; // empty for initialising
const std::string& getName () const { return m_name; }
const std::string& getDescription () const { return m_description; }
const std::string& getHerringStyle() const { return m_herring_style;}
const std::string& getFilename () const { return m_filename; }
const std::string& getTrack(size_t track_index) const { assert(track_index < m_tracks.size()); return m_tracks[track_index]; }
size_t getTrackCount() const { return m_tracks.size(); }
const int& getLaps(size_t lap_index) const { assert(lap_index < m_tracks.size()); return m_laps[lap_index]; }
const std::string& getName () const { return m_name; }
const std::string& getDescription () const { return m_description; }
const std::string& getHerringStyle() const { return m_herring_style; }
const std::string& getFilename () const { return m_filename; }
const std::string& getTrack(size_t track_index) const { assert(track_index < m_tracks.size());
return m_tracks[track_index]; }
const std::vector<std::string>& getTracks() const {return m_tracks; }
const std::vector<int>& getLaps() const {return m_laps; }
size_t getTrackCount() const {return m_tracks.size(); }
const int& getLaps(size_t lap_index) const {assert(lap_index < m_tracks.size());
return m_laps[lap_index]; }
}
; // CupData

View File

@ -25,7 +25,7 @@
#include <set>
#include "callback_manager.hpp"
class FileManager : public ssgLoaderOptions
class FileManager
{
private:
bool m_is_full_path;

View File

@ -236,7 +236,7 @@ void CharSel::select()
}
}
if (race_manager->getRaceMode() == RaceSetup::RM_GRAND_PRIX)
if (race_manager->getRaceMode() == RaceManager::RM_GRAND_PRIX)
menu_manager->pushMenu(MENUID_NUMKARTS);
else
menu_manager->pushMenu(MENUID_TRACKSEL);

View File

@ -77,15 +77,15 @@ void Difficulty::select()
switch ( widget_manager->getSelectedWgt())
{
case WTOK_EASY:
race_manager->setDifficulty(RD_EASY);
race_manager->setDifficulty(RaceManager::RD_EASY);
menu_manager->pushMenu(MENUID_CHARSEL_P1);
break;
case WTOK_MEDIUM:
race_manager->setDifficulty(RD_MEDIUM);
race_manager->setDifficulty(RaceManager::RD_MEDIUM);
menu_manager->pushMenu(MENUID_CHARSEL_P1);
break;
case WTOK_HARD:
race_manager->setDifficulty(RD_HARD);
race_manager->setDifficulty(RaceManager::RD_HARD);
menu_manager->pushMenu(MENUID_CHARSEL_P1);
break;
case WTOK_QUIT:

View File

@ -94,15 +94,15 @@ void GameMode::select()
switch ( widget_manager->getSelectedWgt() )
{
case WTOK_GP:
race_manager->setRaceMode(RaceSetup::RM_GRAND_PRIX);
race_manager->setRaceMode(RaceManager::RM_GRAND_PRIX);
menu_manager->pushMenu(MENUID_GRANDPRIXSELECT);
break;
case WTOK_QUICKRACE:
race_manager->setRaceMode(RaceSetup::RM_QUICK_RACE);
race_manager->setRaceMode(RaceManager::RM_QUICK_RACE);
menu_manager->pushMenu(MENUID_DIFFICULTY);
break;
case WTOK_TIMETRIAL:
race_manager->setRaceMode(RaceSetup::RM_TIME_TRIAL);
race_manager->setRaceMode(RaceManager::RM_TIME_TRIAL);
menu_manager->pushMenu(MENUID_CHARSEL_P1); //difficulty makes no sense here
break;
case WTOK_BACK:

View File

@ -22,7 +22,7 @@
#include <SDL/SDL.h>
#include "file_manager.hpp"
#include "loader.hpp"
#include "sound_manager.hpp"
#include "grand_prix_ending.hpp"
#include "kart_properties_manager.hpp"
@ -60,16 +60,16 @@ GrandPrixEnd::GrandPrixEnd()
oldContext->makeCurrent();
const unsigned int MAX_STR_LEN = 60;
const unsigned int NUM_KARTS = world->getNumKarts();
const unsigned int NUM_KARTS = race_manager->getNumKarts();
int *scores = new int[NUM_KARTS];
int *position = new int[NUM_KARTS];
double *race_time = new double[NUM_KARTS];
for( unsigned int i = 0; i < NUM_KARTS; ++i )
for( unsigned int kart_id = 0; kart_id < NUM_KARTS; ++kart_id )
{
position[i] = i;
scores[i] = race_manager->getKartScore(i);
race_time[i] = race_manager->getKartOverallTime(i);
position[kart_id] = kart_id;
scores[kart_id] = race_manager->getKartScore(kart_id);
race_time[kart_id] = race_manager->getOverallTime(kart_id);
}
//Bubblesort
@ -102,12 +102,9 @@ GrandPrixEnd::GrandPrixEnd()
}
} while(!sorted);
Kart *kart;
kart = world->getKart(position[0]);
static char output[MAX_MESSAGE_LENGTH];
snprintf(output, sizeof(output),
_("The winner is %s!"),kart->getName().c_str());
_("The winner is %s!"),race_manager->getKartName(position[0]).c_str());
widget_manager->addWgt( WTOK_TITLE, 60, 10);
widget_manager->showWgtRect(WTOK_TITLE);
widget_manager->showWgtText(WTOK_TITLE);
@ -121,9 +118,8 @@ GrandPrixEnd::GrandPrixEnd()
{
char sTime[20];
TimeToString(race_time[i], sTime);
kart = world->getKart(position[i]);
sprintf((char*)(m_score + MAX_STR_LEN * i), "%d. %s %d %s",
i + 1, kart->getName().c_str(), scores[i], sTime );
i + 1, race_manager->getKartName(position[i]).c_str(), scores[i], sTime );
widget_manager->addWgt(WTOK_FIRSTKART + i, 40, 5);
widget_manager->showWgtRect(WTOK_FIRSTKART + i);
@ -185,7 +181,7 @@ GrandPrixEnd::~GrandPrixEnd()
//going white after finishing the grandprix
// FIXME: I think this is not necessary anymore after the
// texture bug fix (r733) - but I can't currently test this.
file_manager->shared_textures.removeAll();
loader->shared_textures.removeAll();
}
//-----------------------------------------------------------------------------

View File

@ -53,6 +53,11 @@ NumKarts::NumKarts()
widget_manager->showWgtRect(WTOK_NUMLAPS);
widget_manager->showWgtText(WTOK_NUMLAPS);
m_num_karts = race_manager->getNumKarts();
// Follow the leader needs at least three karts
if(race_manager->getRaceMode() == RaceManager::RM_FOLLOW_LEADER)
{
m_num_karts = std::max(3,m_num_karts);
}
snprintf(m_kart_label, MAX_MESSAGE_LENGTH, _("Karts: %d"), m_num_karts);
widget_manager->setWgtText(WTOK_NUMLAPS, m_kart_label);
widget_manager->breakLine();
@ -80,7 +85,8 @@ NumKarts::NumKarts()
widget_manager->addWgt(WTOK_CONTINUE, 30, 7);
widget_manager->showWgtRect(WTOK_CONTINUE);
widget_manager->showWgtText(WTOK_CONTINUE);
if (race_manager->getRaceMode() == RaceSetup::RM_GRAND_PRIX)
if (race_manager->getRaceMode() == RaceManager::RM_GRAND_PRIX ||
race_manager->getRaceMode() == RaceManager::RM_FOLLOW_LEADER )
widget_manager->setWgtText(WTOK_CONTINUE, _("Start race"));
else
widget_manager->setWgtText(WTOK_CONTINUE, _("Continue"));
@ -112,7 +118,15 @@ void NumKarts::select()
switch (WGT)
{
case WTOK_LESS:
m_num_karts = std::max(race_manager->getNumPlayers(), m_num_karts-1);
// Follow the leader needs at least three karts
if(race_manager->getRaceMode() == RaceManager::RM_FOLLOW_LEADER)
{
m_num_karts = std::max(3,m_num_karts-1);
}
else
{
m_num_karts = std::max((int)race_manager->getNumPlayers(), m_num_karts-1);
}
snprintf(m_kart_label, MAX_MESSAGE_LENGTH, "Karts: %d", m_num_karts);
widget_manager->setWgtText(WTOK_NUMLAPS, m_kart_label);
break;
@ -123,8 +137,9 @@ void NumKarts::select()
break;
case WTOK_CONTINUE:
race_manager->setNumKarts(m_num_karts);
if (race_manager->getRaceMode() == RaceSetup::RM_GRAND_PRIX)
race_manager->start();
if (race_manager->getRaceMode() == RaceManager::RM_GRAND_PRIX ||
race_manager->getRaceMode() == RaceManager::RM_FOLLOW_LEADER )
race_manager->startNew();
else
menu_manager->pushMenu(MENUID_NUMLAPS);
break;

View File

@ -117,7 +117,7 @@ void NumLaps::select()
break;
case WTOK_START:
race_manager->setNumLaps(laps);
race_manager->start();
race_manager->startNew();
break;
case WTOK_QUIT:
menu_manager->popMenu();

View File

@ -167,21 +167,21 @@ RaceGUI::handle(GameAction ga, int value)
switch (ga)
{
case GA_DEBUG_ADD_SPARK:
if (world->m_race_setup.getNumPlayers() ==1 )
if (world->getNumPlayers() ==1 )
{
Kart* kart = world->getPlayerKart(0);
kart->setCollectable(COLLECT_SPARK, 10000);
}
break;
case GA_DEBUG_ADD_MISSILE:
if (world->m_race_setup.getNumPlayers() ==1 )
if (world->getNumPlayers() ==1 )
{
Kart* kart = world->getPlayerKart(0);
kart->setCollectable(COLLECT_MISSILE, 10000);
}
break;
case GA_DEBUG_ADD_HOMING:
if (world->m_race_setup.getNumPlayers() ==1 )
if (world->getNumPlayers() ==1 )
{
Kart* kart = world->getPlayerKart(0);
kart->setCollectable(COLLECT_HOMING, 10000);
@ -232,7 +232,7 @@ RaceGUI::handle(GameAction ga, int value)
void RaceGUI::update(float dt)
{
assert(world != NULL);
drawStatusText(world->m_race_setup, dt);
drawStatusText(dt);
cleanupMessages();
BaseGUI::update( dt );
@ -365,7 +365,7 @@ void RaceGUI::drawPlayerIcons ()
// draw text
int red=255, green=255, blue=255;
int numLaps = world->m_race_setup.m_num_laps;
int numLaps = race_manager->getNumLaps();
if(lap>=numLaps)
{ // kart is finished, display in green
red=0; blue=0;
@ -745,13 +745,15 @@ void RaceGUI::drawSpeed(Kart* kart, int offset_x, int offset_y,
void RaceGUI::drawLap(Kart* kart, int offset_x, int offset_y,
float ratio_x, float ratio_y )
{
// Don't display laps in follow the leader mode
if(race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER) return;
float maxRatio = std::max(ratio_x, ratio_y);
char str[256];
offset_x += (int)(120*ratio_x);
offset_y += (int)(70*maxRatio);
if ( kart->getLap() >= world->m_race_setup.m_num_laps )
if ( kart->getLap() >= race_manager->getNumLaps())
{
sprintf(str, _("Finished"));
font_race->PrintShadow(str, (int)(48*maxRatio), offset_x, offset_y);
@ -763,7 +765,7 @@ void RaceGUI::drawLap(Kart* kart, int offset_x, int offset_y,
offset_y -= (int)(50*ratio_y);
sprintf(str, "%d/%d", kart->getLap()<0?0:kart->getLap()+1,
world->m_race_setup.m_num_laps);
race_manager->getNumLaps());
font_race->PrintShadow(str, (int)(48*maxRatio), offset_x, offset_y);
}
} // drawLap
@ -856,7 +858,7 @@ void RaceGUI::drawMusicDescription()
} // drawMusicDescription
//-----------------------------------------------------------------------------
void RaceGUI::drawStatusText (const RaceSetup& raceSetup, const float dt)
void RaceGUI::drawStatusText(const float dt)
{
assert(world != NULL);
@ -907,7 +909,7 @@ void RaceGUI::drawStatusText (const RaceSetup& raceSetup, const float dt)
}
if(world->isStartPhase())
{
for(int i=0; i<raceSetup.getNumPlayers(); i++)
for(unsigned int i=0; i<world->getNumPlayers(); i++)
{
if(world->getPlayerKart(i)->earlyStartPenalty())
{
@ -920,14 +922,14 @@ void RaceGUI::drawStatusText (const RaceSetup& raceSetup, const float dt)
float split_screen_ratio_x, split_screen_ratio_y;
split_screen_ratio_x = split_screen_ratio_y = 1.0;
if(raceSetup.getNumPlayers() >= 2)
if(world->getNumPlayers() >= 2)
split_screen_ratio_y = 0.5;
if(raceSetup.getNumPlayers() >= 3)
if(world->getNumPlayers() >= 3)
split_screen_ratio_x = 0.5;
if ( world->isRacePhase() )
{
const int numPlayers = raceSetup.getNumPlayers();
const int numPlayers = world->getNumPlayers();
for(int pla = 0; pla < numPlayers; pla++)
{

View File

@ -30,6 +30,7 @@
#include "player_kart.hpp"
#include "player.hpp"
#include "world.hpp"
#include "race_manager.hpp"
class InputMap;
class RaceSetup;
@ -55,10 +56,18 @@ class RaceGUI: public BaseGUI
m_message = message;
m_font_size = size;
m_kart = kart;
m_end_time = time>=0.0f ? world->getTime()+time : -1.0f;
m_end_time = time>=0.0f
? (race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER
?world->getTime()-time
:world->getTime()+time )
: -1.0f;
m_red=red; m_blue=blue; m_green=green;
}
bool done() const {return m_end_time<0 || world->getTime()>m_end_time;}
// in follow leader the clock counts backwards
bool done() const {return m_end_time<0 ||
(race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER
? world->getTime()<m_end_time
: world->getTime()>m_end_time);}
};
public:
@ -83,7 +92,7 @@ private:
AllMessageType m_messages;
/* Display informat on screen */
void drawStatusText (const RaceSetup& raceSetup, const float dt);
void drawStatusText (const float dt);
void drawEnergyMeter (Kart *player_kart,
int offset_x, int offset_y,
float ratio_x, float ratio_y );

View File

@ -69,7 +69,7 @@ RaceMenu::RaceMenu()
widget_manager->setWgtText(WTOK_RESTART_RACE, _("Restart Race"));
widget_manager->breakLine();
if(world->m_race_setup.m_mode==RaceSetup::RM_QUICK_RACE)
if(race_manager->getRaceMode()==RaceManager::RM_QUICK_RACE)
{
widget_manager->addWgt(WTOK_SETUP_NEW_RACE, 30, 7);
widget_manager->setWgtText(WTOK_SETUP_NEW_RACE, _("Setup New Race"));

View File

@ -98,7 +98,7 @@ RaceResultsGUI::RaceResultsGUI()
TimeToString(T, sTime);
//This shows position + driver name + time + points earned + total points
if(world->m_race_setup.m_mode==RaceSetup::RM_GRAND_PRIX)
if(race_manager->getRaceMode()==RaceManager::RM_GRAND_PRIX)
{
sprintf((char*)(m_score + MAX_STR_LEN * i), "%d. %s %s +%d %d",
KART->getPosition(), KART_NAME.c_str(), sTime,
@ -159,7 +159,7 @@ RaceResultsGUI::RaceResultsGUI()
widget_manager->setWgtText( WTOK_CONTINUE, _("Continue"));
} else
{
if(world->m_race_setup.m_mode==RaceSetup::RM_GRAND_PRIX)
if(race_manager->getRaceMode()==RaceManager::RM_GRAND_PRIX)
{
widget_manager->setWgtText( WTOK_CONTINUE, _("Continue Grand Prix"));
}
@ -173,7 +173,7 @@ RaceResultsGUI::RaceResultsGUI()
widget_manager->setWgtText( WTOK_RESTART_RACE, _("Race in this track again"));
widget_manager->breakLine();
if(world->m_race_setup.m_mode==RaceSetup::RM_QUICK_RACE)
if(race_manager->getRaceMode()==RaceManager::RM_QUICK_RACE)
{
widget_manager->addWgt( WTOK_SETUP_NEW_RACE, 60, 7);
widget_manager->setWgtText( WTOK_SETUP_NEW_RACE, _("Setup New Race"));
@ -204,15 +204,17 @@ void RaceResultsGUI::select()
switch( widget_manager->getSelectedWgt() )
{
case WTOK_CONTINUE:
// Gets called when:
// 1) something was unlocked
// 2) a Grand Prix is run
// 3) "back to the main menu" otherwise
world->unpause();
race_manager->next();
break;
case WTOK_RESTART_RACE:
world->unpause();
menu_manager->popMenu();
// TODO: Maybe let this go through the race_manager for
// more flexibility.
world->restartRace();
race_manager->restartRace();
break;
case WTOK_SETUP_NEW_RACE:
world->unpause();

View File

@ -269,7 +269,7 @@ void TrackSel::select()
}
const Track* TRACK = track_manager->getTrack(CLICKED_TOKEN - WTOK_TRACK0);
race_manager->setTrack(TRACK->getIdent());
if(race_manager->getRaceMode()==RaceSetup::RM_TIME_TRIAL)
if(race_manager->getRaceMode()==RaceManager::RM_TIME_TRIAL)
{
menu_manager->pushMenu(MENUID_NUMLAPS);
}

View File

@ -19,12 +19,12 @@
#include <stdexcept>
#include "highscore_manager.hpp"
#include "race_manager.hpp"
#include "lisp/parser.hpp"
#include "lisp/writer.hpp"
#include "translation.hpp"
#include "string_utils.hpp"
#include "file_manager.hpp"
#include "race_setup.hpp"
#include "user_config.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
@ -171,11 +171,7 @@ void HighscoreManager::Save()
} // Save
// -----------------------------------------------------------------------------
Highscores* HighscoreManager::getHighscores(const Highscores::HighscoreType highscore_type,
const int num_karts,
const RaceDifficulty difficulty,
const std::string track,
const int number_of_laps)
Highscores* HighscoreManager::getHighscores(const Highscores::HighscoreType highscore_type)
{
Highscores *highscores = 0;
@ -184,8 +180,9 @@ Highscores* HighscoreManager::getHighscores(const Highscores::HighscoreType high
for(type_all_scores::iterator i = m_allScores.begin();
i != m_allScores.end(); i++)
{
if((*i)->matches(highscore_type, num_karts, difficulty, track,
number_of_laps))
if((*i)->matches(highscore_type, race_manager->getNumKarts(),
race_manager->getDifficulty(), race_manager->getTrackName(),
race_manager->getNumLaps()))
{
return (*i);
}
@ -201,19 +198,13 @@ Highscores* HighscoreManager::getHighscores(const Highscores::HighscoreType high
// If it's one of the fastest HIGHSCORE_LEN results, it is put into the
// list and the new position (1 ... HIGHSCORE_LEN) is returned, otherwise 0.
Highscores * HighscoreManager::addResult(const Highscores::HighscoreType highscore_type,
const int num_karts,
const RaceDifficulty difficulty,
const std::string track,
const std::string kart_name,
const std::string name,
const float time,
const int number_of_laps)
const float time)
{
Highscores *highscores = getHighscores(highscore_type, num_karts,
difficulty, track, number_of_laps);
Highscores *highscores = getHighscores(highscore_type);
if(highscores->addData(highscore_type, num_karts, difficulty,
track, kart_name, name, time, number_of_laps) >0)
if(highscores->addData(highscore_type, kart_name, name, time) >0)
{
Save();
}

View File

@ -26,7 +26,6 @@
#include "highscores.hpp"
#include "lisp/lisp.hpp"
#include "race_setup.hpp"
class HighscoreManager
{
public:
@ -44,14 +43,10 @@ public:
HighscoreManager();
~HighscoreManager();
void Save();
Highscores *getHighscores(const Highscores::HighscoreType highscore_type,
const int num_karts, const RaceDifficulty difficulty,
const std::string track, const int number_of_laps);
Highscores *getHighscores(const Highscores::HighscoreType highscore_type);
Highscores *addResult (const Highscores::HighscoreType highscore_type,
const int num_karts, const RaceDifficulty difficulty,
const std::string track, const std::string kart_name,
const std::string name, const float time,
const int number_of_laps);
const std::string kart_name,
const std::string name, const float time);
}; // HighscoreManager
extern HighscoreManager* highscore_manager;

View File

@ -19,6 +19,8 @@
#include <stdexcept>
#include "highscores.hpp"
#include "race_manager.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
@ -81,7 +83,7 @@ void Highscores::Write(lisp::Writer *writer)
// -----------------------------------------------------------------------------
int Highscores::matches(HighscoreType highscore_type,
int num_karts, RaceDifficulty difficulty,
int num_karts, RaceManager::Difficulty difficulty,
const std::string &track, const int number_of_laps)
{
return (m_highscore_type == highscore_type &&
@ -96,10 +98,8 @@ int Highscores::matches(HighscoreType highscore_type,
* be in the highscore list, the new position (1-HIGHSCORE_LEN) is returned,
* otherwise a 0.
*/
int Highscores::addData(const HighscoreType highscore_type, const int num_karts,
const RaceDifficulty difficulty, const std::string track,
const std::string kart_name, const std::string name,
const float time, const int number_of_laps)
int Highscores::addData(const HighscoreType highscore_type, const std::string kart_name,
const std::string name, const float time)
{
int position=-1;
for(int i=0; i<HIGHSCORE_LEN; i++)
@ -127,11 +127,11 @@ int Highscores::addData(const HighscoreType highscore_type, const int num_karts,
if(position>=0)
{
m_track = track;
m_track = race_manager->getTrackName();
m_highscore_type = highscore_type;
m_number_of_karts = num_karts;
m_difficulty = difficulty;
m_number_of_laps = number_of_laps;
m_number_of_karts = race_manager->getNumKarts();
m_difficulty = race_manager->getDifficulty();
m_number_of_laps = race_manager->getNumLaps();
m_name[position] = name;
m_time[position] = time;
m_kart_name[position] = kart_name;

View File

@ -25,7 +25,7 @@
#include "lisp/lisp.hpp"
#include "lisp/writer.hpp"
#include "race_setup.hpp"
#include "race_manager.hpp"
class Highscores
{
@ -50,12 +50,10 @@ public:
void Read (const lisp::Lisp* const node);
void Write (lisp::Writer* writer);
int matches (HighscoreType highscore_type, int num_karts,
const RaceDifficulty difficulty, const std::string &track,
const int number_of_laps);
int addData (const HighscoreType highscore_type, const int num_karts,
const RaceDifficulty difficulty, const std::string track,
const std::string kart_name, const std::string name,
const float time, const int number_of_laps);
const RaceManager::Difficulty difficulty,
const std::string &track, const int number_of_laps);
int addData (const HighscoreType highscore_type, const std::string kart_name,
const std::string name, const float time);
int getNumberEntries() const;
void getEntry (int number, std::string &kart_name,
std::string &name, float *const time) const;

View File

@ -61,14 +61,14 @@ float History::GetNextDelta()
void History::Save()
{
FILE *fd = fopen("history.dat","w");
int nKarts = world->getNumKarts();
int nKarts = race_manager->getNumKarts();
#ifdef VERSION
fprintf(fd, "Version: %s\n", VERSION);
#endif
fprintf(fd, "numkarts: %d\n", nKarts);
fprintf(fd, "numplayers: %d\n", world->m_race_setup.getNumPlayers());
fprintf(fd, "difficulty: %d\n", world->m_race_setup.getDifficulty());
fprintf(fd, "track: %s\n", world->m_track->getIdent().c_str());
fprintf(fd, "numplayers: %d\n", race_manager->getNumPlayers());
fprintf(fd, "difficulty: %d\n", race_manager->getDifficulty());
fprintf(fd, "track: %s\n", world->getTrack()->getIdent().c_str());
int k;
for(k=0; k<nKarts; k++)
@ -142,7 +142,7 @@ void History::Load()
fprintf(stderr,"WARNING: No difficulty found in history file.\n");
exit(-2);
}
race_manager->setDifficulty((RaceDifficulty)n);
race_manager->setDifficulty((RaceManager::Difficulty)n);
fgets(s, 1023, m_fd);
if(sscanf(s, "track: %s",s1)!=1)

View File

@ -1271,10 +1271,6 @@
RelativePath="../../../src\race_manager.hpp"
>
</File>
<File
RelativePath="../../../src\race_setup.hpp"
>
</File>
<File
RelativePath="../../../src\replay_base.hpp"
>

View File

@ -21,6 +21,7 @@
#include <iostream>
#include <plib/ssg.h>
#include "loader.hpp"
#include "herring_manager.hpp"
#include "sound_manager.hpp"
#include "file_manager.hpp"
@ -33,6 +34,7 @@
#include "kart.hpp"
#include "ssg_help.hpp"
#include "physics.hpp"
#include "kart_properties_manager.hpp"
#include "gui/menu_manager.hpp"
#include "gui/race_gui.hpp"
#include "translation.hpp"
@ -117,7 +119,7 @@ void KartParticleSystem::particle_delete (int , Particle* )
{} // particle_delete
//=============================================================================
Kart::Kart (const KartProperties* kartProperties_, int position_ ,
Kart::Kart (const std::string& kart_name, int position_ ,
sgCoord init_pos)
: TerrainInfo(1),
#if defined(WIN32) && !defined(__CYGWIN__)
@ -129,7 +131,7 @@ Kart::Kart (const KartProperties* kartProperties_, int position_ ,
# pragma warning(1:4355)
#endif
{
m_kart_properties = kartProperties_;
m_kart_properties = kart_properties_manager->getKart(kart_name);
m_grid_position = position_ ;
m_num_herrings_gobbled = 0;
m_finished_race = false;
@ -434,13 +436,13 @@ void Kart::doLapCounting ()
// Only increase the lap counter and set the new time if the
// kart hasn't already finished the race (otherwise the race_gui
// will begin another countdown).
if(m_race_lap+1<=world->m_race_setup.m_num_laps)
if(m_race_lap+1<=race_manager->getNumLaps())
{
setTimeAtLap(world->getTime());
m_race_lap++ ;
}
// Sound manager makes sure that only the first call switches the music
if(m_race_lap==world->m_race_setup.m_num_laps-1) // last lap started
if(m_race_lap==race_manager->getNumLaps()-1) // last lap started
{
sound_manager->switchToFastMusic();
}
@ -1083,7 +1085,7 @@ void Kart::loadData()
float r [ 2 ] = { -10.0f, 100.0f } ;
m_smokepuff = new ssgSimpleState ();
m_smokepuff -> setTexture (file_manager->createTexture ("smoke.rgb", true, true, true)) ;
m_smokepuff -> setTexture (loader->createTexture("smoke.rgb", true, true, true)) ;
m_smokepuff -> setTranslucent () ;
m_smokepuff -> enable ( GL_TEXTURE_2D ) ;
m_smokepuff -> setShadeModel ( GL_SMOOTH ) ;
@ -1198,7 +1200,7 @@ float Kart::estimateFinishTime ()
// Finish time is the time needed for the whole race with
// the average speed computed above.
return world->m_race_setup.m_num_laps*world->m_track->getTrackLength()
return race_manager->getNumLaps()*world->getTrack()->getTrackLength()
/ average_speed;
} // estimateFinishTime

View File

@ -134,7 +134,7 @@ protected:
void load_wheels (ssgBranch* obj);
public:
Kart(const KartProperties* kartProperties_, int position_,
Kart(const std::string& kart_name, int position_,
sgCoord init_pos);
virtual ~Kart();
void loadData();
@ -237,9 +237,9 @@ public:
class TrafficDriver : public Kart
{
public:
TrafficDriver (const KartProperties* kartProperties_, sgVec3 _pos,
TrafficDriver (const std::string& kart_name, sgVec3 _pos,
sgCoord init_pos)
: Kart (kartProperties_, 0, init_pos )
: Kart (kart_name, 0, init_pos )
{
sgCopyVec3 ( m_reset_pos.xyz, _pos ) ;
reset () ;

View File

@ -164,13 +164,13 @@ int handleCmdLine(int argc, char **argv)
switch (atoi(argv[i+1]))
{
case 1:
race_manager->setDifficulty(RD_EASY);
race_manager->setDifficulty(RaceManager::RD_EASY);
break;
case 2:
race_manager->setDifficulty(RD_MEDIUM);
race_manager->setDifficulty(RaceManager::RD_MEDIUM);
break;
case 3:
race_manager->setDifficulty(RD_HARD);
race_manager->setDifficulty(RaceManager::RD_HARD);
break;
}
}
@ -389,19 +389,20 @@ void InitTuxkart()
kart_properties_manager = new KartPropertiesManager();
projectile_manager = new ProjectileManager ();
collectable_manager = new CollectableManager ();
race_manager = new RaceManager ();
callback_manager = new CallbackManager ();
herring_manager = new HerringManager ();
attachment_manager = new AttachmentManager ();
highscore_manager = new HighscoreManager ();
track_manager->loadTrackList();
sound_manager->addMusicToTracks();
stk_config->load(file_manager->getConfigFile("stk_config.data"));
race_manager = new RaceManager ();
// default settings for Quickstart
race_manager->setNumPlayers(1);
race_manager->setNumLaps (3);
race_manager->setRaceMode (RaceSetup::RM_QUICK_RACE);
race_manager->setDifficulty(RD_MEDIUM);
stk_config->load(file_manager->getConfigFile("stk_config.data"));
race_manager->setRaceMode (RaceManager::RM_QUICK_RACE);
race_manager->setDifficulty(RaceManager::RD_MEDIUM);
}
//=============================================================================
@ -465,7 +466,7 @@ int main(int argc, char *argv[] )
{
// This will setup the race manager etc.
history->Load();
race_manager->start();
race_manager->startNew();
game_manager->run();
// well, actually run() will never return, since
// it exits after replaying history (see history::GetNextDT()).
@ -491,7 +492,7 @@ int main(int argc, char *argv[] )
//race_manager->setTrack ("tuxtrack");
//race_manager->setTrack ("sandtrack");
//race_manager->setTrack ("race");
race_manager->start();
race_manager->startNew();
}
}
else // profile
@ -501,9 +502,9 @@ int main(int argc, char *argv[] )
// =========
race_manager->setNumPlayers(1);
race_manager->setPlayerKart(0, kart_properties_manager->getKart("tuxkart")->getIdent());
race_manager->setRaceMode (RaceSetup::RM_QUICK_RACE);
race_manager->setDifficulty(RD_HARD);
race_manager->start();
race_manager->setRaceMode (RaceManager::RM_QUICK_RACE);
race_manager->setDifficulty(RaceManager::RD_HARD);
race_manager->startNew();
}
game_manager->run();
@ -516,6 +517,7 @@ int main(int argc, char *argv[] )
/* Program closing...*/
user_config->saveConfig();
delete inputDriver;
if (user_config->m_log_errors) //close logfiles

View File

@ -238,7 +238,7 @@ void PlayerKart::addMessages()
// 1) check if the player is going in the wrong direction
// ------------------------------------------------------
if(world->m_race_setup.m_difficulty==RD_EASY)
if(race_manager->getDifficulty()==RaceManager::RD_EASY)
{
float angle_diff = getCoord()->hpr[0] - world->m_track->m_angle[getSector()];
if(angle_diff > 180.0f) angle_diff -= 360.0f;

View File

@ -42,10 +42,10 @@ private:
void steer(float, int);
public:
PlayerKart(const KartProperties *kart_properties,
PlayerKart(const std::string& kart_name,
int position, Player *_player,
sgCoord init_pos, Camera *cam) :
Kart(kart_properties, position, init_pos), m_player(_player),
Kart(kart_name, position, init_pos), m_player(_player),
m_penalty_time(0.0), m_camera(cam) {reset(); }
int earlyStartPenalty () {return m_penalty_time>0; }
@ -59,6 +59,7 @@ public:
virtual void setPosition (int p);
int isPlayerKart () const {return 1;}
Camera* getCamera () {return m_camera;}
void reset();
};

View File

@ -20,7 +20,6 @@
#include <iostream>
#include "track_manager.hpp"
#include "race_setup.hpp"
#include "game_manager.hpp"
#include "kart_properties_manager.hpp"
#include "race_manager.hpp"
@ -31,239 +30,25 @@
#include "user_config.hpp"
#include "stk_config.hpp"
RaceManager* race_manager= NULL;
void
RaceMode::next()
{
exit_race();
}
//-----------------------------------------------------------------------------
void
RaceMode::exit_race()
{
menu_manager->switchToMainMenu();
scene->clear();
delete world;
world = 0;
race_manager->m_active_race = false;
}
//=============================================================================
GrandPrixMode::GrandPrixMode(const std::vector<std::string>& players_,
const CupData& cup_,
RaceDifficulty difficulty_,
int numKarts_)
: m_difficulty(difficulty_), m_num_karts(numKarts_), m_players(players_),
m_cup(cup_), m_track(0)
{
const int NUM_PLAYERS = (int)m_players.size();
std::vector<std::string> kart_names;
if(m_num_karts < 0 ) m_num_karts = stk_config->m_max_karts;
if((size_t)m_num_karts < m_players.size()) m_num_karts = (int)m_players.size();
kart_names.resize(m_num_karts);
for(int i = 0; i < NUM_PLAYERS; ++i)
{
/*Players position is behind the AI in the first race*/
kart_names[m_num_karts-1 - i] = m_players[NUM_PLAYERS - 1 - i];
}
kart_properties_manager->fillWithRandomKarts(kart_names);
const int NUM_AI_KARTS = m_num_karts - NUM_PLAYERS;
//Add the AI karts
for(int i = 0; i < NUM_AI_KARTS; ++i)
m_karts.push_back(KartStatus(kart_names[i], 0, 0.0f, i, NUM_PLAYERS));
//Add the player karts
for(int i = 0; i < NUM_PLAYERS; ++i)
m_karts.push_back(KartStatus(kart_names[i+NUM_AI_KARTS], 0, 0.0f, i+NUM_AI_KARTS, i));
}
//-----------------------------------------------------------------------------
void
GrandPrixMode::start_race(int n)
{
RaceSetup raceSetup;
raceSetup.m_mode = RaceSetup::RM_GRAND_PRIX;
raceSetup.m_difficulty = m_difficulty;
raceSetup.m_num_laps = m_cup.getLaps(n);
raceSetup.m_track = m_cup.getTrack(n);
raceSetup.m_karts.resize(m_karts.size());
raceSetup.m_players.resize(m_players.size());
raceSetup.setHerringStyle(m_cup.getHerringStyle());
if (n == 0) //The first race, Players start at the back
{
for(int i = 0; i < int(m_karts.size()); ++i)
{
raceSetup.m_karts[m_karts[i].prev_finish_pos] = m_karts[i].ident;
if (m_karts[i].player < int(m_players.size()))
{
raceSetup.m_players[m_karts[i].player] = m_karts[i].prev_finish_pos;
}
}
}
else //subsequent races where order of grid is determined by score
{
std::sort(m_karts.begin(), m_karts.end());//sort karts by increasing score
//reverse kart order if flagged in stk_config
if (stk_config->m_grid_order)
{
std::reverse(m_karts.begin(), m_karts.end());
}
for(int i = 0;i < int(m_karts.size()); ++i)
{
raceSetup.m_karts[i] = m_karts[i].ident;
if (m_karts[i].player < int(m_players.size()))
{
raceSetup.m_players[m_karts[i].player] = i;
}
}
}
// the constructor assigns this object to the global
// variable world. Admittedly a bit ugly, but simplifies
// handling of objects which get created in the constructor
// and need world to be defined.
new World(raceSetup);
}
//-----------------------------------------------------------------------------
void
GrandPrixMode::start()
{
start_race(m_track);
}
//-----------------------------------------------------------------------------
void
GrandPrixMode::next()
{
m_track += 1;
if (m_track < int(m_cup.getTrackCount()))
{
scene->clear();
start_race(m_track);
}
else
{
exit_race();
}
}
//-----------------------------------------------------------------------------
void
GrandPrixMode::exit_race()
{
if (m_track < int(m_cup.getTrackCount()))
{
RaceMode::exit_race();
}
else
{
unlock_manager->grandPrixFinished();
menu_manager->switchToGrandPrixEnding();
}
}
//=============================================================================
QuickRaceMode::QuickRaceMode(const std::string& track_,
const std::vector<std::string>& players_,
RaceDifficulty difficulty_,
int numKarts_, int numLaps_)
: m_track(track_), m_players(players_), m_difficulty(difficulty_),
m_num_karts(numKarts_), m_num_laps(numLaps_)
{
if(m_num_karts < 0 ) m_num_karts = stk_config->m_max_karts;
if((size_t)m_num_karts < m_players.size()) m_num_karts = (int)m_players.size();
}
//-----------------------------------------------------------------------------
void
QuickRaceMode::start()
{
RaceSetup raceSetup;
raceSetup.m_mode = RaceSetup::RM_QUICK_RACE;
raceSetup.m_difficulty = m_difficulty;
raceSetup.m_track = m_track;
raceSetup.m_num_laps = m_num_laps;
raceSetup.m_karts.resize(m_num_karts);
const int FIRST_PLAYER = m_num_karts - (int)m_players.size();
for(int i = 0; i < int(m_players.size()); ++i)
{
raceSetup.m_karts[FIRST_PLAYER + i] = m_players[i]; // Players starts last in the race
raceSetup.m_players.push_back(FIRST_PLAYER + i);
}
kart_properties_manager->fillWithRandomKarts(raceSetup.m_karts);
// the constructor assigns this object to the global
// variable world. Admittedly a bit ugly, but simplifies
// handling of objects which get created in the constructor
// and need world to be defined.
new World(raceSetup);
}
//=============================================================================
TimeTrialMode::TimeTrialMode(const std::string& track_, const std::string& kart_,
const int& numLaps_)
: m_track(track_), m_kart(kart_), m_num_laps(numLaps_)
{}
//-----------------------------------------------------------------------------
void
TimeTrialMode::start()
{
RaceSetup raceSetup;
raceSetup.m_mode = RaceSetup::RM_TIME_TRIAL;
raceSetup.m_track = m_track;
raceSetup.m_num_laps = m_num_laps;
raceSetup.m_difficulty = RD_HARD;
raceSetup.m_karts.push_back(m_kart);
raceSetup.m_players.push_back(0);
// the constructor assigns this object to the global
// variable world. Admittedly a bit ugly, but simplifies
// handling of objects which get created in the constructor
// and need world to be defined.
new World(raceSetup);
}
//=============================================================================
RaceManager::RaceManager()
{
m_mode = 0;
m_num_karts = user_config->m_karts;
m_difficulty = RD_MEDIUM;
m_race_mode = RaceSetup::RM_QUICK_RACE;
m_track = "race";
m_active_race = false;
m_players.push_back("tuxkart");
}
m_num_karts = user_config->m_karts;
m_difficulty = RD_MEDIUM;
m_race_mode = RM_QUICK_RACE;
m_track_number = 0;
m_active_race = false;
m_score_for_position = stk_config->m_scores;
setTrack("race");
setPlayerKart(0, "tuxkart");
} // RaceManager
//-----------------------------------------------------------------------------
RaceManager::~RaceManager()
{
delete m_mode;
}
} // ~RaceManager
//-----------------------------------------------------------------------------
void RaceManager::reset()
@ -273,80 +58,167 @@ void RaceManager::reset()
} // reset
//-----------------------------------------------------------------------------
void
RaceManager::setPlayerKart(int player, const std::string& kart)
void RaceManager::setPlayerKart(unsigned int player, const std::string& kart)
{
if (player >= 0 && player < 4)
{
if (player >= getNumPlayers())
setNumPlayers(player+1);
m_players[player] = kart;
m_player_karts[player] = kart;
}
else
{
fprintf(stderr, "Warning: player '%d' does not exists.\n", player);
}
}
} // setPlayerKart
//-----------------------------------------------------------------------------
void
RaceManager::setNumPlayers(int num)
void RaceManager::setNumPlayers(int num)
{
m_players.resize(num);
for(Players::iterator i = m_players.begin(); i != m_players.end(); ++i)
m_player_karts.resize(num);
for(PlayerKarts::iterator i = m_player_karts.begin(); i != m_player_karts.end(); ++i)
{
if (i->empty())
{
*i = "tuxkart";
}
}
}
} // setNumPlayers
//-----------------------------------------------------------------------------
void
RaceManager::start()
void RaceManager::setTrack(const std::string& track)
{
m_tracks.clear();
m_tracks.push_back(track);
} // setTrack
//-----------------------------------------------------------------------------
void RaceManager::startNew()
{
if(m_race_mode==RM_GRAND_PRIX) // GP: get tracks and laps from cup object
{
m_tracks = m_cup.getTracks();
m_num_laps = m_cup.getLaps();
}
assert(m_player_karts.size() > 0);
// command line parameters: negative numbers=all karts
if(m_num_karts < 0 ) m_num_karts = stk_config->m_max_karts;
if((size_t)m_num_karts < m_player_karts.size())
m_num_karts = (int)m_player_karts.size();
// Create the list of all kart names to use
// ========================================
std::vector<std::string> kart_names;
kart_names.resize(m_num_karts);
for(unsigned int i = 0; i < m_player_karts.size(); i++)
{
/*Players position is behind the AI in the first race*/
kart_names[m_num_karts-1 - i] = m_player_karts[m_player_karts.size() - 1 - i];
}
kart_properties_manager->fillWithRandomKarts(kart_names);
// Create the kart status data structure to keep track of scores, times, ...
// ==========================================================================
const int num_ai_karts = m_num_karts - (int)m_player_karts.size();
m_kart_status.clear();
for(int i=0; i<m_num_karts; i++)
{
// AI karts have -1 as player
bool is_player = i>=num_ai_karts; // players start at the back
m_kart_status.push_back(KartStatus(kart_names[i], i,
is_player ? i-num_ai_karts : -1 ) );
} // for i<m_num_karts
// Then start the race with the first track
// ========================================
m_track_number = 0;
startNextRace();
} // startNew
//-----------------------------------------------------------------------------
void RaceManager::startNextRace()
{
m_num_finished_karts = 0;
m_num_finished_players = 0;
delete m_mode;
assert(m_players.size() > 0);
switch(m_race_mode)
{
case RaceSetup::RM_GRAND_PRIX:
m_mode = new GrandPrixMode(m_players, m_cup, m_difficulty, m_num_karts);
break;
case RaceSetup::RM_TIME_TRIAL:
m_mode = new TimeTrialMode(m_track, m_players[0], m_num_laps);
break;
case RaceSetup::RM_QUICK_RACE:
m_mode = new QuickRaceMode(m_track, m_players, m_difficulty, m_num_karts, m_num_laps);
break;
default:
assert(!"Unknown game mode");
}
// if subsequent race, sort kart status structure
// ==============================================
if (m_track_number > 0)
{
std::sort(m_kart_status.begin(), m_kart_status.end());//sort karts by increasing scor
//reverse kart order if flagged in stk_config
if (stk_config->m_grid_order)
{
std::reverse(m_kart_status.begin(), m_kart_status.end());
}
} // not first race
m_mode->start();
// the constructor assigns this object to the global
// variable world. Admittedly a bit ugly, but simplifies
// handling of objects which get created in the constructor
// and need world to be defined.
new World();
m_active_race = true;
}
} // startNextRace
//-----------------------------------------------------------------------------
void
RaceManager::next()
void RaceManager::next()
{
assert(m_mode);
m_num_finished_karts = 0;
m_num_finished_players = 0;
m_mode->next();
}
m_track_number++;
if(m_track_number<(int)m_tracks.size())
{
scene->clear();
startNextRace();
}
else
{
exit_race();
}
} // next
//-----------------------------------------------------------------------------
void
RaceManager::exit_race()
void RaceManager::exit_race()
{
m_mode->exit_race();
}
// Only display the grand prix result screen if all tracks
// were finished, and not when a race is aborted.
if(m_race_mode==RM_GRAND_PRIX && m_track_number==m_tracks.size())
{
unlock_manager->grandPrixFinished();
menu_manager->switchToGrandPrixEnding();
}
else
{
menu_manager->switchToMainMenu();
}
scene->clear();
delete world;
world = 0;
m_active_race = false;
} // exit_Race
//-----------------------------------------------------------------------------
void RaceManager::addKartResult(int kart, int pos, float time)
{
m_kart_status[kart].m_score += m_score_for_position[pos-1];
m_kart_status[kart].m_last_score = m_score_for_position[pos-1];
m_kart_status[kart].m_overall_time += time;
m_kart_status[kart].m_last_time = time;
} // addKartResult
//-----------------------------------------------------------------------------
void RaceManager::restartRace()
{
// Subtract last score from all karts:
for(int i=0; i<m_num_karts; i++)
{
m_kart_status[i].m_score -= m_kart_status[i].m_last_score;
m_kart_status[i].m_overall_time -= m_kart_status[i].m_last_time;
}
world->restartRace();
} // restartRace
/* EOF */

View File

@ -24,176 +24,125 @@
#include <algorithm>
#include <string>
#include "race_setup.hpp"
#include "cup_data.hpp"
class RaceMode
{
public:
virtual ~RaceMode() {}; // avoid compiler warning
virtual void start() = 0; // Start the mode and go into the first race
virtual void next (); // go to the next race if there is any, otherwise main menu
virtual void exit_race (); // go directly to main menu
virtual void addKartScore (int kart, int pos) {}
virtual int getKartScore (int kart) const {return 0;}
virtual std::string getKartName(int kart) const { return "";}
virtual int getPositionScore(int pos ) const {return 0;}
virtual void addKartOverallTime (int kart, float race_time) {}
virtual double getKartOverallTime (int kart) const {return 0.0f;}
};
class GrandPrixMode : public RaceMode
{
private:
void start_race(int n);
RaceDifficulty m_difficulty;
int m_num_karts;
struct KartStatus
{
std::string ident;//The .tkkf filename without the .tkkf
int score;
double overall_time;
int prev_finish_pos;
int player;//Which player controls the kart, for the AI this is
//the number of players.
KartStatus(const std::string& ident_, const int& score_,
const double& overall_time_, const int& prev_finish_pos_,
const int& player_) :
ident(ident_), score(score_), overall_time(overall_time_),
prev_finish_pos(prev_finish_pos_), player(player_){}
};
public:
std::vector<std::string> m_players;
CupData m_cup;
std::vector<KartStatus> m_karts;
int m_track;
GrandPrixMode(const std::vector<std::string>& players_,
const CupData& cup_,
RaceDifficulty difficulty_,
int numKarts);
virtual ~GrandPrixMode() {}
void start();
void next();
void exit_race();
int getKartScore (int kart) const { return m_karts[kart].score;}
int getPositionScore(int pos) const { return pos>4 ? 0 : 4-pos;}
std::string getKartName(int kart) const { return m_karts[kart].ident;}
void addKartScore (int kart, int pos)
{
m_karts[kart].score +=
getPositionScore(pos);
}
double getKartOverallTime (int kart) const {return m_karts[kart].overall_time;}
void addKartOverallTime (int kart, float race_time)
{
m_karts[kart].overall_time += race_time;
}
friend bool operator< (const KartStatus& left, const KartStatus& right)
{
if (left.score < right.score) return true;
return false;
}
};
class QuickRaceMode : public RaceMode
{
public:
std::string m_track;
std::vector<std::string> m_players;
RaceDifficulty m_difficulty;
int m_num_karts, m_num_laps;
QuickRaceMode(const std::string& track_,
const std::vector<std::string>& players_,
RaceDifficulty difficulty_,
int numKarts, int numLaps);
virtual ~QuickRaceMode() {}
void start();
};
class TimeTrialMode : public RaceMode
{
public:
std::string m_track;
std::string m_kart;
int m_num_laps;
TimeTrialMode(const std::string& track_, const std::string& kart_,
const int& numLaps_);
virtual ~TimeTrialMode() {}
void start();
};
/** RaceManager keeps track of the game mode, number of players and
such, the GUI calls the RaceManager to setup and start a race,
grandprix or similar stuff */
/** The race manager has two functions:
1) it stores information about the race the user selected (e.g. number
of karts, track, race mode etc.)
2) when a race is started, it creates the world, and keeps track of
score during the race. When a race is finished, it deletes the world,
and (depending on race mode) starts the next race by creating a new
world).
Information in the race manager is considered to be more static, sometimes
the world has similar functions showing the current state. E.g.: the
race manager keeps track of the number of karts with which the race was
started, while world keeps track of the number of karts currently in the
race (consider a race mode like follow the leader where karts can get
eliminated).
The race manager handles all race types as a kind of grand prix. E.g.:
a quick race is basically a GP with only one track (so the race manager
keeps track of scores even though no scores are used in a quick race)
**/
class RaceManager
{
public:
enum RaceModeType { RM_TIME_TRIAL, RM_QUICK_RACE, RM_GRAND_PRIX,
RM_FOLLOW_LEADER };
enum Difficulty { RD_EASY, RD_MEDIUM, RD_HARD };
private:
RaceMode* m_mode;
RaceDifficulty m_difficulty;
RaceSetup::RaceMode m_race_mode;
typedef std::vector<std::string> Players;
Players m_players;
std::string m_track;
struct KartStatus
{
std::string m_ident; // The .tkkf filename without the .tkkf
int m_score; // score for this kart
int m_last_score; // needed for restart race
double m_overall_time; // sum of times of all races
double m_last_time; // needed for restart
int m_prev_finish_pos; // previous finished position
int m_player_id; // player controling the kart, for AI: -1
bool m_is_eliminated; // for mini games which can eliminate karts
KartStatus(const std::string& ident, const int& prev_finish_pos,
const int& player_id) :
m_ident(ident), m_score(0), m_last_score(0),
m_overall_time(0.0f), m_last_time(0.0f),
m_prev_finish_pos(prev_finish_pos), m_player_id(player_id),
m_is_eliminated(false)
{}
}; // KartStatus
std::vector<KartStatus> m_kart_status;
Difficulty m_difficulty;
RaceModeType m_race_mode;
typedef std::vector<std::string> PlayerKarts;
PlayerKarts m_player_karts;
std::vector<std::string> m_tracks;
std::vector<int> m_num_laps;
std::vector<int> m_score_for_position;
int m_track_number;
CupData m_cup;
int m_num_laps;
int m_num_karts;
unsigned int m_num_finished_karts;
unsigned int m_num_finished_players;
void startNextRace(); // start a next race
public:
bool m_active_race; //True if there is a race
public:
RaceManager();
~RaceManager();
RaceSetup::RaceMode getRaceMode() const { return m_race_mode; }
void setPlayerKart(int player, const std::string& kart);
void setPlayerKart(unsigned int player, const std::string& kart);
void setNumPlayers(int num);
void reset();
void setGrandPrix(const CupData &cup_) { m_cup = cup_; }
void setDifficulty(RaceDifficulty diff_) { m_difficulty = diff_; }
void setNumLaps(int num) { m_num_laps = num; }
void setTrack(const std::string& track_) { m_track = track_; }
void setRaceMode(RaceSetup::RaceMode mode) { m_race_mode = mode; }
void setNumKarts(int num) { m_num_karts = num; }
int getNumKarts() const { return m_num_karts; }
int getNumPlayers() const { return (int)m_players.size(); }
int getNumLaps() const { return m_num_laps; }
CupData *getGrandPrix() { return &m_cup; }
unsigned int getFinishedKarts() const { return m_num_finished_karts; }
unsigned int getFinishedPlayers() const { return m_num_finished_players; }
int getKartScore(int kart ) const { return m_mode->getKartScore(kart); }
int getPositionScore(int pos) const { return m_mode->getPositionScore(pos);}
std::string getKartName(int kart) const { return m_mode->getKartName(kart); }
void addKartScore(int kart, int pos) { m_mode->addKartScore(kart, pos); }
void addKartOverallTime(int kart, float race_time) {m_mode->addKartOverallTime(kart, race_time); }
double getKartOverallTime(int kart) {return m_mode->getKartOverallTime(kart); }
void addFinishedKarts(int num) { m_num_finished_karts += num; }
void PlayerFinishes() { m_num_finished_players++; }
int allPlayerFinished() {return m_num_finished_players==m_players.size();}
int raceIsActive() {return m_active_race; }
void setGrandPrix(const CupData &cup) { m_cup = cup; }
void setDifficulty(Difficulty diff) { m_difficulty = diff; }
void setNumLaps(int num) { m_num_laps.clear();
m_num_laps.push_back(num); }
void setTrack(const std::string& track);
void setRaceMode(RaceModeType mode) { m_race_mode = mode; }
void setNumKarts(int num) { m_num_karts = num; }
void addKartResult(int kart, int pos, float time);
RaceModeType getRaceMode() const { return m_race_mode; }
unsigned int getNumKarts() const { return m_num_karts; }
unsigned int getNumPlayers() const { return (int)m_player_karts.size();}
int getNumLaps() const { return m_num_laps[m_track_number];}
Difficulty getDifficulty() const { return m_difficulty; }
const std::string& getTrackName() const { return m_tracks[m_track_number]; }
const CupData *getGrandPrix() const { return &m_cup; }
unsigned int getFinishedKarts() const { return m_num_finished_karts; }
unsigned int getFinishedPlayers() const { return m_num_finished_players; }
const std::string& getKartName(int kart) const
{ return m_kart_status[kart].m_ident;}
const std::string& getHerringStyle() const
{ return m_cup.getHerringStyle(); }
int getKartScore(int kart) const { return m_kart_status[kart].m_score;}
int getPositionScore(int p) const { return m_score_for_position[p-1];}
double getOverallTime(int kart) const {return m_kart_status[kart].m_overall_time;}
bool isEliminated(int kart) const { return m_kart_status[kart].m_is_eliminated;}
void addFinishedKarts(int num) { m_num_finished_karts += num; }
void PlayerFinishes() { m_num_finished_players++; }
int allPlayerFinished() const {return m_num_finished_players==m_player_karts.size();}
int raceIsActive() const { return m_active_race; }
bool isPlayer(int kart) const {return m_kart_status[kart].m_player_id>-1; }
void setMirror() {/*FIXME*/}
void setReverse(){/*FIXME*/}
void start(); // start a new race
void next(); // start the next race or go back to the start screen
void exit_race();
void startNew(); // start new race/GP/...
void next(); // start the next race or go back to the start screen
void restartRace(); // restart same race again
void exit_race(); // exit a race (and don't start the next one)
friend bool operator< (const KartStatus& left, const KartStatus& right)
{
return (left.m_score < right.m_score);
}
};
extern RaceManager *race_manager;

View File

@ -1,74 +0,0 @@
// $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
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_RACESETUP_H
#define HEADER_RACESETUP_H
#include <string>
#include <vector>
enum RaceDifficulty { RD_EASY, RD_MEDIUM, RD_HARD };
/** A class that manages all configurations that are needed for a
single race */
class RaceSetup
{
protected:
std::string m_herring_style;
public:
enum RaceMode { RM_TIME_TRIAL, RM_QUICK_RACE, RM_GRAND_PRIX };
RaceSetup()
{
m_mode = RM_QUICK_RACE;
m_difficulty = RD_EASY;
m_num_laps = 3;
m_track = "race";
m_herring_style = "";
}
RaceMode m_mode;
RaceDifficulty m_difficulty;
int m_num_laps;
/** Ident of the track to use */
std::string m_track;
// FIXME: This could probally be a bit more robust/easier to understand
typedef std::vector<int> Players;
/** Positions of the karts which should be controlled by
players */
Players m_players;
typedef std::vector<std::string> Karts;
/** kart idents that should be used in the race, the karts
will be used in the order in which they are given */
Karts m_karts;
unsigned int getNumKarts() const { return (unsigned int) m_karts.size(); }
int getNumPlayers() const { return (int)m_players.size(); }
const std::string& getHerringStyle() const { return m_herring_style; }
RaceDifficulty getDifficulty() const { return m_difficulty; }
const void setHerringStyle(const std::string& s) {m_herring_style=s; }
};
#endif
/* EOF */

View File

@ -38,19 +38,19 @@
#include "constants.hpp"
#include "scene.hpp"
#include "world.hpp"
#include "race_manager.hpp"
#include "default_robot.hpp"
DefaultRobot::DefaultRobot( const KartProperties *kart_properties,
DefaultRobot::DefaultRobot(const std::string& kart_name,
int position, sgCoord init_pos ) :
AutoKart( kart_properties, position, init_pos )
AutoKart( kart_name, position, init_pos )
{
m_kart_properties = kart_properties;
reset();
switch( world->m_race_setup.m_difficulty )
switch( race_manager->getDifficulty())
{
case RD_EASY:
case RaceManager::RD_EASY:
m_wait_for_players = true;
m_max_handicap_accel = 0.9f;
m_fallback_tactic = FT_AVOID_TRACK_CRASH;
@ -60,7 +60,7 @@ DefaultRobot::DefaultRobot( const KartProperties *kart_properties,
m_max_start_delay = 0.5f;
m_min_steps = 0;
break;
case RD_MEDIUM:
case RaceManager::RD_MEDIUM:
m_wait_for_players = true;
m_max_handicap_accel = 0.95f;
m_fallback_tactic = FT_PARALLEL;
@ -70,7 +70,7 @@ DefaultRobot::DefaultRobot( const KartProperties *kart_properties,
m_max_start_delay = 0.4f;
m_min_steps = 1;
break;
case RD_HARD:
case RaceManager::RD_HARD:
m_wait_for_players = false;
m_max_handicap_accel = 1.0f;
m_fallback_tactic = FT_FAREST_POINT;
@ -383,7 +383,7 @@ void DefaultRobot::handle_acceleration( const float DELTA )
{
//Find if any player is ahead of this kart
bool player_winning = false;
for( int i = 0; i < world->m_race_setup.getNumPlayers(); ++i )
for(unsigned int i = 0; i < race_manager->getNumPlayers(); ++i )
if( m_race_position > world->getPlayerKart(i)->getPosition() )
{
player_winning = true;
@ -909,5 +909,5 @@ void DefaultRobot::find_curve()
// FIXME: 0.9 is the tire grip - but this was never used. For now this
// 0.9 is left in place to reproduce the same results and AI behaviour,
// but this function should be updated to bullet physics
m_curve_target_speed = sgSqrt(get_approx_radius(m_track_sector, i) * world->getGravity() * 0.9f);
m_curve_target_speed = sgSqrt(get_approx_radius(m_track_sector, i) * world->m_track->getGravity() * 0.9f);
}

View File

@ -127,7 +127,7 @@ private:
int m_sector;
public:
DefaultRobot(const KartProperties *kart_properties, int position,
DefaultRobot(const std::string& kart_name, int position,
sgCoord init_pos);
void update (float delta) ;

View File

@ -36,7 +36,7 @@
#include "collectable_manager.hpp"
#include "attachment_manager.hpp"
#include "projectile_manager.hpp"
#include "file_manager.hpp"
#include "loader.hpp"
#include "gui/menu_manager.hpp"
#include "widget_manager.hpp"
#include "player.hpp"
@ -133,7 +133,13 @@ SDLDriver::initStickInfos()
bool match;
vector<StickInfo *>::iterator si_ite = si->begin();
while (si_ite != si->end())
// FIXME: Visual Studio triggers an exception (in debug mode) when si
// becomes empty (incompatible iterators). This is apparently caused
// by using erase. For now I added a work around by checking for
// si->size()>0, which solves the problem for me. But I have only one
// gamepad, I'd suspect that with more gamepads the problem still exists.
while (si->size()>0 && si_ite != si->end())
{
match = false;
@ -247,7 +253,7 @@ SDLDriver::setVideoMode(bool resetTextures)
if(resetTextures)
{
// Clear plib internal texture cache
file_manager->endLoad();
loader->endLoad();
// Windows needs to reload all textures, display lists, ... which means
// that all models have to be reloaded. So first, free all textures,

View File

@ -57,6 +57,11 @@ void STKConfig::load(const std::string filename)
exit(-1);
}
if(m_scores.size()==0 || (int)m_scores.size()!=m_max_karts)
{
fprintf(stderr,"Not or not enough scores defined in stk_config");
exit(-1);
}
CHECK_NEG(m_max_karts, "max-karts" );
CHECK_NEG(m_grid_order, "grid-order" );
@ -101,6 +106,7 @@ void STKConfig::load(const std::string filename)
CHECK_NEG(m_bomb_time, "bomb-time" );
CHECK_NEG(m_bomb_time_increase, "bomb-time-increase" );
CHECK_NEG(m_anvil_time, "anvil-time" );
CHECK_NEG(m_anvil_weight, "anvil-weight" );
CHECK_NEG(m_zipper_time, "zipper-time" );
CHECK_NEG(m_zipper_force, "zipper-force" );
CHECK_NEG(m_zipper_speed_gain, "zipper-speed-gain" );
@ -125,7 +131,7 @@ void STKConfig::init_defaults()
m_engine_power = m_jump_impulse = m_brake_factor =
m_anvil_speed_factor = m_time_full_steer = m_wheelie_max_pitch =
m_wheelie_max_speed_ratio = m_wheelie_pitch_rate = m_wheelie_restore_rate =
m_wheelie_speed_boost =
m_wheelie_speed_boost =
m_bomb_time = m_bomb_time_increase= m_anvil_time =
m_zipper_time = m_zipper_force = m_zipper_speed_gain =
m_shortcut_segments =
@ -141,6 +147,7 @@ void STKConfig::init_defaults()
m_max_karts = -100;
m_grid_order = -100;
m_title_music = NULL;
m_scores.clear();
} // init_defaults
//-----------------------------------------------------------------------------
@ -167,6 +174,7 @@ void STKConfig::getAllData(const lisp::Lisp* lisp)
lisp->get("explosion-impulse-objects", m_explosion_impulse_objects);
lisp->get("max-karts", m_max_karts );
lisp->get("grid-order", m_grid_order );
lisp->getVector("scores", m_scores);
std::string title_music;
lisp->get("title-music", title_music );
m_title_music = new MusicInformation(file_manager->getMusicFile(title_music));

View File

@ -45,7 +45,9 @@ public:
float m_explosion_impulse; // impulse affecting each non-hit kart
float m_explosion_impulse_objects;// impulse of explosion on moving objects, e.g. road cones, ...
int m_max_karts; // maximum number of karts
int m_grid_order; // whether grand prix grid is in point order or reverse point order
int m_grid_order; // whether grand prix grid is in point or reverse point order
std::vector<int> m_scores; // scores depending on position
MusicInformation* m_title_music; // filename of the title music to play
STKConfig() : KartProperties() {};

View File

@ -333,6 +333,10 @@ int Track::findOutOfRoadSector
}
} // for i
if(sector==UNKNOWN_SECTOR)
{
printf("unknown sector found.\n");
}
return sector;
} // findOutOfRoadSector

View File

@ -22,6 +22,7 @@
#include "challenges/all_tracks.hpp"
#include "challenges/energy_math_class.hpp"
#include "challenges/win_gotm_cup.hpp"
#include "user_config.hpp"
UnlockManager* unlock_manager=0;
//-----------------------------------------------------------------------------
@ -90,13 +91,14 @@ void UnlockManager::computeActive()
for(AllChallengesType::iterator i =m_all_challenges.begin();
i!=m_all_challenges.end(); i++)
{
// If a challenge is solved, nothing needs to be done
// --------------------------------------------------
// Changed challenge
// -----------------
if((i->second)->isSolved())
{
// The constructor calls computeActive, which actually locks all features,
// so unlock them
unlockFeature(i->second);
// The constructor calls computeActive, which actually locks
// all features, so unlock the solved ones (and don't try to
// save the state, since we are currently reading it)
unlockFeature(i->second, /*save*/ false);
continue;
}
@ -126,7 +128,9 @@ void UnlockManager::computeActive()
i->second->setActive();
} // if solved
} // for i
clearUnlocked();
} // computeActive
//-----------------------------------------------------------------------------
/** This is called when a race is finished. Call all active challenges
*/
@ -162,7 +166,7 @@ void UnlockManager::lockFeature(const std::string& feature)
} // lockFeature
//-----------------------------------------------------------------------------
void UnlockManager::unlockFeature(Challenge* c)
void UnlockManager::unlockFeature(Challenge* c, bool save)
{
const std::string& feature=c->getFeature();
std::map<std::string,bool>::iterator p=m_locked_features.find(feature);
@ -177,6 +181,9 @@ void UnlockManager::unlockFeature(Challenge* c)
// Add to list of recently unlocked features
m_unlocked_features.push_back(c);
c->setSolved(); // reset isActive flag
// Save the new unlock informationxt
if(save) user_config->saveConfig();
} // unlockFeature
//-----------------------------------------------------------------------------

View File

@ -48,7 +48,7 @@ public:
void clearUnlocked () {m_unlocked_features.clear(); }
void raceFinished ();
void grandPrixFinished ();
void unlockFeature (Challenge* c);
void unlockFeature (Challenge* c, bool save=true);
void lockFeature (const std::string& feature);
bool isLocked (const std::string& feature);
}; // UnlockManager

View File

@ -732,7 +732,7 @@ UserConfig::writeStickConfigs(lisp::Writer *writer)
writer->beginList("stick-configs");
count = m_stickconfigs.size();
count = (int)m_stickconfigs.size();
writer->write("count", count);
for (int i = 0; i < count; i++)

View File

@ -56,7 +56,7 @@
World* world = 0;
World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
World::World()
#ifdef HAVE_GHOST_REPLAY
, m_p_replay_player(NULL)
#endif
@ -64,7 +64,6 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
delete world;
world = this;
m_phase = SETUP_PHASE;
m_track = NULL;
m_clock = 0.0f;
@ -75,89 +74,81 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
// Grab the track file
try
{
m_track = track_manager->getTrack(m_race_setup.m_track) ;
m_track = track_manager->getTrack(race_manager->getTrackName());
}
catch(std::runtime_error)
{
char msg[MAX_ERROR_MESSAGE_LENGTH];
snprintf(msg, sizeof(msg),
"Track '%s' not found.\n",m_race_setup.m_track.c_str());
"Track '%s' not found.\n",race_manager->getTrackName().c_str());
throw std::runtime_error(msg);
}
// Create the physics
m_physics = new Physics(getGravity());
m_physics = new Physics(m_track->getGravity());
assert(m_race_setup.m_karts.size() > 0);
assert(race_manager->getNumKarts() > 0);
// 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.
loadTrack() ;
int pos = 0;
int playerIndex = 0;
for (RaceSetup::Karts::iterator i = m_race_setup.m_karts.begin() ;
i != m_race_setup.m_karts.end() ; ++i )
for(unsigned int position=0; position<race_manager->getNumKarts(); position++)
{
sgCoord init_pos;
m_track->getStartCoords(pos, &init_pos);
m_track->getStartCoords(position, &init_pos);
Kart* newkart;
const std::string& kart_name=race_manager->getKartName(position);
if(user_config->m_profile)
{
// In profile mode, load only the old kart
newkart = new DefaultRobot (kart_properties_manager->getKart("tuxkart"), pos,
init_pos);
// Create a camera for the last kart (since this way more of the
// karts can be seen.
if((i+1)==m_race_setup.m_karts.end())
newkart = new DefaultRobot(kart_name, position, init_pos);
// Create a camera for the last kart (since this way more of the
// karts can be seen.
if(position==race_manager->getNumKarts()-1)
{
scene->createCamera(m_race_setup.getNumPlayers(), playerIndex);
scene->createCamera(race_manager->getNumPlayers(), playerIndex);
}
}
else
{
if (std::find(m_race_setup.m_players.begin(),
m_race_setup.m_players.end(), pos) != m_race_setup.m_players.end())
if (race_manager->isPlayer(position))
{
Camera *cam = scene->createCamera(m_race_setup.getNumPlayers(), playerIndex);
Camera *cam = scene->createCamera(race_manager->getNumPlayers(), playerIndex);
// the given position belongs to a player
newkart = new PlayerKart (kart_properties_manager->getKart(*i), pos,
&(user_config->m_player[playerIndex]),
init_pos, cam);
newkart = new PlayerKart(kart_name, position,
&(user_config->m_player[playerIndex]),
init_pos, cam);
m_player_karts.push_back((PlayerKart*)newkart);
playerIndex++;
}
else
{
newkart = loadRobot(kart_properties_manager->getKart(*i), pos,
init_pos);
newkart = loadRobot(kart_name, position, init_pos);
}
} // if !user_config->m_profile
if(user_config->m_replay_history)
{
history->LoadKartData(newkart, pos);
history->LoadKartData(newkart, position);
}
newkart -> getModelTransform() -> clrTraversalMaskBits(SSGTRAV_ISECT|SSGTRAV_HOT);
scene->add ( newkart -> getModelTransform() ) ;
m_kart.push_back(newkart);
pos++;
} // for i
resetAllKarts();
#ifdef SSG_BACKFACE_COLLISIONS_SUPPORTED
//ssgSetBackFaceCollisions ( m_race_setup.mirror ) ;
//ssgSetBackFaceCollisions ( !not defined! race_manager->mirror ) ;
#endif
Highscores::HighscoreType hst = (m_race_setup.m_mode==RaceSetup::RM_TIME_TRIAL)
Highscores::HighscoreType hst = (race_manager->getRaceMode()==RaceManager::RM_TIME_TRIAL)
? Highscores::HST_TIMETRIAL_OVERALL_TIME
: Highscores::HST_RACE_OVERALL_TIME;
m_highscores = highscore_manager->getHighscores(hst, (int)m_kart.size(),
m_race_setup.m_difficulty,
m_track->getName(),
m_race_setup.m_num_laps);
m_highscores = highscore_manager->getHighscores(hst);
callback_manager->initAll();
menu_manager->switchToRace();
@ -167,7 +158,7 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
m_phase = user_config->m_profile ? RACE_PHASE : SETUP_PHASE;
#ifdef HAVE_GHOST_REPLAY
m_replay_recorder.initRecorder( m_race_setup.getNumKarts() );
m_replay_recorder.initRecorder( race_manager->getNumKarts() );
m_p_replay_player = new ReplayPlayer;
if( !loadReplayHumanReadable( "test1" ) )
@ -273,7 +264,7 @@ void World::update(float dt)
// Don't record the time for the last kart, since it didn't finish
// the race - unless it's timetrial (then there is only one kart)
unsigned int karts_to_enter = (m_race_setup.m_mode==RaceSetup::RM_TIME_TRIAL)
unsigned int karts_to_enter = (race_manager->getRaceMode()==RaceManager::RM_TIME_TRIAL)
? (unsigned int)m_kart.size() : (unsigned int)m_kart.size()-1;
for(unsigned int pos=0; pos<karts_to_enter; pos++)
{
@ -282,16 +273,13 @@ void World::update(float dt)
PlayerKart *k = (PlayerKart*)m_kart[index[pos]];
Highscores::HighscoreType hst = (m_race_setup.m_mode==RaceSetup::RM_TIME_TRIAL)
? Highscores::HST_TIMETRIAL_OVERALL_TIME
: Highscores::HST_RACE_OVERALL_TIME;
if(m_highscores->addData(hst, (int)m_kart.size(),
m_race_setup.m_difficulty,
m_track->getName(),
k->getName(),
k->getPlayer()->getName(),
k->getFinishTime(),
m_race_setup.m_num_laps)>0)
Highscores::HighscoreType hst = (race_manager->getRaceMode()==
RaceManager::RM_TIME_TRIAL)
? Highscores::HST_TIMETRIAL_OVERALL_TIME
: Highscores::HST_RACE_OVERALL_TIME;
if(m_highscores->addData(hst, k->getName(),
k->getPlayer()->getName(),
k->getFinishTime())>0 )
{
highscore_manager->Save();
}
@ -350,14 +338,13 @@ bool World::saveReplayHumanReadable( std::string const &filename ) const
#endif
fprintf(fd, "Version: %s\n", version);
fprintf(fd, "numkarts: %d\n", m_kart.size());
fprintf(fd, "numplayers: %d\n", m_race_setup.getNumPlayers());
fprintf(fd, "difficulty: %d\n", m_race_setup.m_difficulty);
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 (RaceSetup::Karts::const_iterator i = m_race_setup.m_karts.begin() ;
i != m_race_setup.m_karts.end() ; ++i )
for(int i=0; i<race_manager->getNumKarts(); i++)
{
fprintf(fd, "model %d: %s\n", i-m_race_setup.m_karts.begin(), (*i).c_str());
fprintf(fd, "model %d: %s\n", i, race_manager->getKartName(i).c_str());
}
if( !m_replay_recorder.saveReplayHumanReadable( fd ) )
{
@ -440,9 +427,12 @@ void World::updateRaceStatus(float dt)
#endif
}
break;
case GO_PHASE : if(m_clock>1.0) m_phase=RACE_PHASE; break;
case GO_PHASE : if(m_clock>1.0) m_phase=RACE_PHASE; break;
default : break;
} // switch
// Now handling of normal race
// ===========================
m_clock += dt;
/*if all players have finished, or if only one kart is not finished when
@ -453,12 +443,11 @@ void World::updateRaceStatus(float dt)
for ( Karts::size_type i = 0; i < m_kart.size(); ++i)
{
// FIXME: this part should be done as part of Kart::update
if ((m_kart[i]->getLap () >= m_race_setup.m_num_laps) && !m_kart[i]->raceIsFinished())
if ((m_kart[i]->getLap () >= race_manager->getNumLaps()) && !m_kart[i]->raceIsFinished())
{
m_kart[i]->setFinishingState(m_clock);
race_manager->addKartScore((int)i, m_kart[i]->getPosition());
race_manager->addKartOverallTime((int) i, m_clock);
race_manager->addKartResult((int)i, m_kart[i]->getPosition(), m_clock);
++new_finished_karts;
if(m_kart[i]->isPlayerKart())
@ -480,7 +469,7 @@ void World::updateRaceStatus(float dt)
// 1) All karts are finished --> end the race
// ==========================================
if(race_manager->getFinishedKarts() >= m_race_setup.getNumKarts() )
if(race_manager->getFinishedKarts() >= race_manager->getNumKarts() )
{
m_phase = FINISH_PHASE;
if(user_config->m_profile<0) // profiling number of laps -> print stats
@ -524,8 +513,8 @@ void World::updateRaceStatus(float dt)
{
const float est_finish_time = m_kart[i]->estimateFinishTime();
m_kart[i]->setFinishingState(est_finish_time);
race_manager->addKartScore((int)i, m_kart[i]->getPosition());
race_manager->addKartOverallTime((int) i, est_finish_time);
race_manager->addKartResult((int)i, m_kart[i]->getPosition(),
est_finish_time);
} // if !raceIsFinished
} // for i
}
@ -563,17 +552,17 @@ void World::loadTrack()
// remove old herrings (from previous race), and remove old
// track specific herring models
herring_manager->cleanup();
if(m_race_setup.m_mode == RaceSetup::RM_GRAND_PRIX)
if(race_manager->getRaceMode()== RaceManager::RM_GRAND_PRIX)
{
try
{
herring_manager->loadHerringStyle(m_race_setup.getHerringStyle());
herring_manager->loadHerringStyle(race_manager->getHerringStyle());
}
catch(std::runtime_error)
{
fprintf(stderr, "The cup '%s' contains an invalid herring style '%s'.\n",
race_manager->getGrandPrix()->getName().c_str(),
race_manager->getGrandPrix()->getHerringStyle().c_str());
race_manager->getHerringStyle().c_str());
fprintf(stderr, "Please fix the file '%s'.\n",
race_manager->getGrandPrix()->getFilename().c_str());
}
@ -616,7 +605,7 @@ void World::restartRace()
scene->reset();
#ifdef HAVE_GHOST_REPLAY
m_replay_recorder.destroy();
m_replay_recorder.initRecorder( m_race_setup.getNumKarts() );
m_replay_recorder.initRecorder( race_manager->getNumKarts() );
if( m_p_replay_player )
{
@ -627,8 +616,8 @@ void World::restartRace()
} // restartRace
//-----------------------------------------------------------------------------
Kart* World::loadRobot(const KartProperties *kart_properties, int position,
sgCoord init_pos)
Kart* World::loadRobot(const std::string& kart_name, int position,
sgCoord init_pos)
{
Kart* currentRobot;
@ -639,13 +628,11 @@ Kart* World::loadRobot(const KartProperties *kart_properties, int position,
switch(rand() % NUM_ROBOTS)
{
case 0:
currentRobot = new DefaultRobot(kart_properties, position,
init_pos);
currentRobot = new DefaultRobot(kart_name, position, init_pos);
break;
default:
std::cerr << "Warning: Unknown robot, using default." << std::endl;
currentRobot = new DefaultRobot(kart_properties, position,
init_pos);
currentRobot = new DefaultRobot(kart_name, position, init_pos);
break;
}

View File

@ -22,7 +22,6 @@
#include <vector>
#include <plib/ssg.h>
#include "race_setup.hpp"
#include "track.hpp"
#include "player_kart.hpp"
#include "physics.hpp"
@ -43,7 +42,6 @@ public:
/** resources, this should be put in a separate class or replaced by a smart
* resource manager
*/
RaceSetup m_race_setup;
enum Phase {
// Game setup, e.g. track loading
@ -71,7 +69,7 @@ public:
/** debug text that will be overlaid to the screen */
std::string m_debug_text[10];
World(const RaceSetup& raceSetup);
World();
virtual ~World();
void update(float delta);
// Note: GO_PHASE is both: start phase and race phase
@ -80,23 +78,23 @@ public:
void restartRace();
void disableRace(); // Put race into limbo phase
PlayerKart* getPlayerKart(int player)
PlayerKart* getPlayerKart(int player) const
{
return (PlayerKart*)m_kart[m_race_setup.m_players[player]];
return m_player_karts[player];
}
Kart* getKart(int kartId)
Kart* getKart(int kartId) const
{
assert(kartId >= 0 &&
kartId < int(m_kart.size()));
return m_kart[kartId];
}
unsigned int getNumKarts() const {return (int)m_kart.size(); }
unsigned int getNumKarts() const {return (int)m_kart.size(); }
unsigned int getNumPlayers() const {return (unsigned int)m_player_karts.size();}
/** Returns the phase of the game */
Phase getPhase() const { return m_phase; }
float getGravity() const { return m_track->getGravity(); }
Physics *getPhysics() const { return m_physics; }
Track *getTrack() const { return m_track; }
Kart* getFastestKart() const { return m_fastest_kart; }
@ -110,6 +108,7 @@ public:
private:
Karts m_kart;
std::vector<PlayerKart*> m_player_karts;
float m_finish_delay_start_time;
Physics* m_physics;
float m_fastest_lap;
@ -122,8 +121,8 @@ private:
void loadTrack();
void updateRaceStatus(float dt);
void resetAllKarts();
Kart* loadRobot(const KartProperties *kart_properties, int position,
sgCoord init_pos);
Kart* loadRobot(const std::string& kart_name, int position,
sgCoord init_pos);
#ifdef HAVE_GHOST_REPLAY
private: