hikerstk bd3ab7926f 1) Fixed 'moving physics', i.e. objects on the track that
can be pushed around by karts (currently only used in
   tux tollway).
2) Removed support for magnet.
3) Some code cleanup for missiles etc.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1379 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2008-01-09 12:09:55 +00:00

352 lines
10 KiB
C++

// $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.
#include <iostream>
#include "loader.hpp"
#include "track_manager.hpp"
#include "race_setup.hpp"
#include "game_manager.hpp"
#include "kart_properties_manager.hpp"
#include "race_manager.hpp"
#include "gui/menu_manager.hpp"
#include "world.hpp"
#include "scene.hpp"
#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, 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, 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
{
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");
}
//-----------------------------------------------------------------------------
RaceManager::~RaceManager()
{
delete m_mode;
}
//-----------------------------------------------------------------------------
void RaceManager::reset()
{
m_num_finished_karts = 0;
m_num_finished_players = 0;
} // reset
//-----------------------------------------------------------------------------
void
RaceManager::setPlayerKart(int player, const std::string& kart)
{
if (player >= 0 && player < 4)
{
if (player >= getNumPlayers())
setNumPlayers(player+1);
m_players[player] = kart;
}
else
{
fprintf(stderr, "Warning: player '%d' does not exists.\n", player);
}
}
//-----------------------------------------------------------------------------
void
RaceManager::setNumPlayers(int num)
{
m_players.resize(num);
for(Players::iterator i = m_players.begin(); i != m_players.end(); ++i)
{
if (i->empty())
{
*i = "tuxkart";
}
}
}
//-----------------------------------------------------------------------------
void
RaceManager::start()
{
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");
}
m_mode->start();
m_active_race = true;
}
//-----------------------------------------------------------------------------
void
RaceManager::next()
{
assert(m_mode);
m_num_finished_karts = 0;
m_num_finished_players = 0;
m_mode->next();
}
//-----------------------------------------------------------------------------
void
RaceManager::exit_race()
{
m_mode->exit_race();
}
/* EOF */