Back to index

supertuxkart  0.5+dfsg1
race_manager.cpp
Go to the documentation of this file.
00001 
00002 //  $Id: race_manager.cpp 2111 2008-05-31 07:04:30Z cosmosninja $
00003 //
00004 //  SuperTuxKart - a fun racing game with go-kart
00005 //  Copyright (C) 2006 SuperTuxKart-Team
00006 //
00007 //  This program is free software; you can redistribute it and/or
00008 //  modify it under the terms of the GNU General Public License
00009 //  as published by the Free Software Foundation; either version 2
00010 //  of the License, or (at your option) any later version.
00011 //
00012 //  This program is distributed in the hope that it will be useful,
00013 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //  GNU General Public License for more details.
00016 //
00017 //  You should have received a copy of the GNU General Public License
00018 //  along with this program; if not, write to the Free Software
00019 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020 
00021 #include <iostream>
00022 
00023 #include "track_manager.hpp"
00024 #include "game_manager.hpp"
00025 #include "kart_properties_manager.hpp"
00026 #include "race_manager.hpp"
00027 #include "unlock_manager.hpp"
00028 #include "gui/menu_manager.hpp"
00029 #include "world.hpp"
00030 #include "scene.hpp"
00031 #include "user_config.hpp"
00032 #include "stk_config.hpp"
00033 
00034 
00035 RaceManager* race_manager= NULL;
00036 
00037 RaceManager::RaceManager()
00038 {
00039     m_num_karts                = user_config->m_karts;
00040     m_difficulty               = RD_HARD;
00041     m_race_mode                = RM_QUICK_RACE;
00042     m_track_number             = 0;
00043     m_active_race              = false;
00044     m_score_for_position = stk_config->m_scores;
00045     setTrack("race");
00046     setPlayerKart(0, "tuxkart");
00047     m_coin_target               = 0;
00048 }   // RaceManager
00049 
00050 //-----------------------------------------------------------------------------
00051 RaceManager::~RaceManager()
00052 {
00053 }   // ~RaceManager
00054 
00055 //-----------------------------------------------------------------------------
00056 void RaceManager::reset()
00057 {
00058     m_num_finished_karts   = 0;
00059     m_num_finished_players = 0;
00060 }  // reset
00061 
00062 //-----------------------------------------------------------------------------
00063 void RaceManager::setPlayerKart(unsigned int player, const std::string& kart)
00064 {
00065     if (player >= 0 && player < 4)
00066     {
00067         if (player >= getNumPlayers())
00068             setNumPlayers(player+1);
00069         m_player_karts[player] = kart;
00070     }
00071     else
00072     {
00073         fprintf(stderr, "Warning: player '%d' does not exists.\n", player);
00074     }
00075 }   // setPlayerKart
00076 
00077 //-----------------------------------------------------------------------------
00078 void RaceManager::setNumPlayers(int num)
00079 {
00080     m_player_karts.resize(num);
00081     for(PlayerKarts::iterator i = m_player_karts.begin(); i != m_player_karts.end(); ++i)
00082     {
00083         if (i->empty())
00084         {
00085             *i = "tuxkart";
00086         }
00087     }
00088 }   // setNumPlayers
00089 
00090 //-----------------------------------------------------------------------------
00091 void RaceManager::setDifficulty(Difficulty diff)
00092 {
00093     if(diff==RD_SKIDDING)
00094     {
00095         m_difficulty = RD_HARD;
00096         user_config->m_skidding = true;
00097     }
00098     else
00099     {
00100         m_difficulty = diff;
00101         user_config->m_skidding = false;
00102     }
00103 }   // setDifficulty
00104 
00105 //-----------------------------------------------------------------------------
00106 void RaceManager::setTrack(const std::string& track)
00107 {
00108     m_tracks.clear();
00109     m_tracks.push_back(track);
00110 }   // setTrack
00111 
00112 //-----------------------------------------------------------------------------
00113 void RaceManager::startNew()
00114 {
00115     if(m_race_mode==RM_GRAND_PRIX)   // GP: get tracks and laps from cup object
00116     {
00117         m_tracks = m_cup.getTracks();
00118         m_num_laps = m_cup.getLaps();
00119     }
00120     assert(m_player_karts.size() > 0);
00121 
00122     // command line parameters: negative numbers=all karts
00123     if(m_num_karts < 0 ) m_num_karts = stk_config->m_max_karts;
00124     if((size_t)m_num_karts < m_player_karts.size()) 
00125         m_num_karts = (int)m_player_karts.size();
00126 
00127     // Create the list of all kart names to use
00128     // ========================================
00129     std::vector<std::string> kart_names;
00130     kart_names.resize(m_num_karts);
00131     for(unsigned int i = 0; i < m_player_karts.size(); i++)
00132     {
00133         /*Players position is behind the AI in the first race*/
00134         kart_names[m_num_karts-1 - i] = m_player_karts[m_player_karts.size() - 1 - i];
00135     }
00136     kart_properties_manager->fillWithRandomKarts(kart_names);
00137 
00138     // Create the kart status data structure to keep track of scores, times, ...
00139     // ==========================================================================
00140     const int num_ai_karts = m_num_karts - (int)m_player_karts.size();
00141     m_kart_status.clear();
00142     for(int i=0; i<m_num_karts; i++)
00143     {
00144         // AI karts have -1 as player 
00145         bool is_player = i>=num_ai_karts;   // players start at the back
00146         m_kart_status.push_back(KartStatus(kart_names[i], i,
00147                                            is_player ? i-num_ai_karts : -1 ) );
00148     }   // for i<m_num_karts
00149 
00150     // Then start the race with the first track
00151     // ========================================
00152     m_track_number = 0;
00153     startNextRace();
00154 }   // startNew
00155 
00156 //-----------------------------------------------------------------------------
00157 void RaceManager::startNextRace()
00158 {
00159 
00160     m_num_finished_karts   = 0;
00161     m_num_finished_players = 0;
00162 
00163     // if subsequent race, sort kart status structure
00164     // ==============================================
00165     if (m_track_number > 0)
00166     {  
00167         std::sort(m_kart_status.begin(), m_kart_status.end());//sort karts by increasing scor        
00168         //reverse kart order if flagged in stk_config
00169         if (stk_config->m_grid_order)
00170         {
00171             std::reverse(m_kart_status.begin(), m_kart_status.end());
00172         } 
00173     }   // not first race
00174 
00175     // the constructor assigns this object to the global
00176     // variable world. Admittedly a bit ugly, but simplifies
00177     // handling of objects which get created in the constructor
00178     // and need world to be defined.
00179     new World();
00180 
00181     m_active_race = true;
00182 }   // startNextRace
00183 
00184 //-----------------------------------------------------------------------------
00185 void RaceManager::next()
00186 {
00187     m_num_finished_karts   = 0;
00188     m_num_finished_players = 0;
00189     m_track_number++;
00190     if(m_track_number<(int)m_tracks.size())
00191     {
00192         scene->clear();
00193         startNextRace();
00194     }
00195     else
00196     {
00197         exit_race();
00198     }
00199 }   // next
00200 
00201 //-----------------------------------------------------------------------------
00202 void RaceManager::exit_race()
00203 {
00204     // Only display the grand prix result screen if all tracks 
00205     // were finished, and not when a race is aborted.
00206     if(m_race_mode==RM_GRAND_PRIX && m_track_number==(int)m_tracks.size()) 
00207     {
00208         unlock_manager->grandPrixFinished();
00209         menu_manager->switchToGrandPrixEnding();
00210     }
00211     else
00212     {
00213         menu_manager->switchToMainMenu();
00214     }
00215     scene->clear();
00216     delete world;
00217     world          = 0;
00218     m_track_number = 0;
00219     m_active_race  = false;    
00220 }   // exit_Race
00221 
00222 //-----------------------------------------------------------------------------
00223 void RaceManager::addKartResult(int kart, int pos, float time)
00224 {
00225     // In follow the leader mode, kart 0 does not get any points,
00226     // so the position of each kart is actually one better --> decrease pos
00227     if(m_race_mode==RM_FOLLOW_LEADER) 
00228     {
00229         pos--;
00230         // If the position is negative (i.e. follow leader and kart on 
00231         // position 0) set the score of this kart to the lowest possible
00232         // score, since the kart is ahead of the leader
00233         if(pos<=0) pos=stk_config->m_max_karts;
00234     }
00235 
00236     m_kart_status[kart].m_score        += m_score_for_position[pos-1];
00237     m_kart_status[kart].m_last_score    = m_score_for_position[pos-1];
00238     m_kart_status[kart].m_overall_time += time;
00239     m_kart_status[kart].m_last_time     = time;
00240 }   // addKartResult
00241 
00242 //-----------------------------------------------------------------------------
00243 void RaceManager::restartRace()
00244 {
00245     // Subtract last score from all karts:
00246     for(int i=0; i<m_num_karts; i++)
00247     {
00248         m_kart_status[i].m_score        -= m_kart_status[i].m_last_score;
00249         m_kart_status[i].m_overall_time -= m_kart_status[i].m_last_time;
00250     }
00251     world->restartRace();
00252 }   // restartRace
00253 
00254 /* EOF */