1) Applied bugfix for mixing up player karts in AI by SciYann.
2) Added some debug print in case of incorrect kart positions (which I have seen once and never again). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2164 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
0eb36180bd
commit
936f363467
@ -1,156 +1,157 @@
|
||||
// $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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_RACEMANAGER_H
|
||||
#define HEADER_RACEMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <string>
|
||||
#include "cup_data.hpp"
|
||||
|
||||
/** 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, RD_SKIDDING };
|
||||
|
||||
private:
|
||||
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_karts;
|
||||
unsigned int m_num_finished_karts;
|
||||
unsigned int m_num_finished_players;
|
||||
int m_coin_target;
|
||||
|
||||
void startNextRace(); // start a next race
|
||||
|
||||
friend bool operator< (const KartStatus& left, const KartStatus& right)
|
||||
{
|
||||
return (left.m_score < right.m_score);
|
||||
}
|
||||
|
||||
public:
|
||||
bool m_active_race; //True if there is a race
|
||||
|
||||
public:
|
||||
|
||||
RaceManager();
|
||||
~RaceManager();
|
||||
|
||||
void setPlayerKart(unsigned int player, const std::string& kart);
|
||||
void setNumPlayers(int num);
|
||||
void reset();
|
||||
void RaceFinished(const Kart* kart, float time);
|
||||
void setTrack(const std::string& track);
|
||||
void setGrandPrix(const CupData &cup){ m_cup = cup; }
|
||||
void setDifficulty(Difficulty diff);
|
||||
void setNumLaps(int num) { m_num_laps.clear();
|
||||
m_num_laps.push_back(num); }
|
||||
void setRaceMode(RaceModeType mode) { m_race_mode = mode; }
|
||||
void setNumKarts(int num) { m_num_karts = num; }
|
||||
void setCoinTarget(int num) { m_coin_target = num; }
|
||||
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 krt) const { return m_kart_status[krt].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;}
|
||||
int getCoinTarget() const { return m_coin_target; }
|
||||
bool isEliminated(int kart) const { return m_kart_status[kart].m_is_eliminated;}
|
||||
bool raceHasLaps() const { return m_race_mode!=RM_FOLLOW_LEADER;}
|
||||
void eliminate(int kart) { m_kart_status[kart].m_is_eliminated=true;}
|
||||
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 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)
|
||||
};
|
||||
|
||||
extern RaceManager *race_manager;
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
// $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 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_RACEMANAGER_H
|
||||
#define HEADER_RACEMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <string>
|
||||
#include "cup_data.hpp"
|
||||
|
||||
/** 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, RD_SKIDDING };
|
||||
|
||||
private:
|
||||
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_karts;
|
||||
unsigned int m_num_finished_karts;
|
||||
unsigned int m_num_finished_players;
|
||||
int m_coin_target;
|
||||
|
||||
void startNextRace(); // start a next race
|
||||
|
||||
friend bool operator< (const KartStatus& left, const KartStatus& right)
|
||||
{
|
||||
return (left.m_score < right.m_score);
|
||||
}
|
||||
|
||||
public:
|
||||
bool m_active_race; //True if there is a race
|
||||
|
||||
public:
|
||||
|
||||
RaceManager();
|
||||
~RaceManager();
|
||||
|
||||
void setPlayerKart(unsigned int player, const std::string& kart);
|
||||
void setNumPlayers(int num);
|
||||
void reset();
|
||||
void RaceFinished(const Kart* kart, float time);
|
||||
void setTrack(const std::string& track);
|
||||
void setGrandPrix(const CupData &cup){ m_cup = cup; }
|
||||
void setDifficulty(Difficulty diff);
|
||||
void setNumLaps(int num) { m_num_laps.clear();
|
||||
m_num_laps.push_back(num); }
|
||||
void setRaceMode(RaceModeType mode) { m_race_mode = mode; }
|
||||
void setNumKarts(int num) { m_num_karts = num; }
|
||||
void setCoinTarget(int num) { m_coin_target = num; }
|
||||
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 krt) const { return m_kart_status[krt].m_score;}
|
||||
int getkartPlayerId(int krt) const { return m_kart_status[krt].m_player_id;}
|
||||
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;}
|
||||
int getCoinTarget() const { return m_coin_target; }
|
||||
bool isEliminated(int kart) const { return m_kart_status[kart].m_is_eliminated;}
|
||||
bool raceHasLaps() const { return m_race_mode!=RM_FOLLOW_LEADER;}
|
||||
void eliminate(int kart) { m_kart_status[kart].m_is_eliminated=true;}
|
||||
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 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)
|
||||
};
|
||||
|
||||
extern RaceManager *race_manager;
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
@ -95,13 +95,15 @@ World::World()
|
||||
// karts can be positioned properly on (and not in) the tracks.
|
||||
loadTrack() ;
|
||||
|
||||
int playerIndex = 0;
|
||||
m_player_karts.resize(race_manager->getNumPlayers());
|
||||
|
||||
for(unsigned int i=0; i<race_manager->getNumKarts(); i++)
|
||||
{
|
||||
int position = i+1; // position start with 1
|
||||
btTransform init_pos=m_track->getStartTransform(position);
|
||||
Kart* newkart;
|
||||
const std::string& kart_name=race_manager->getKartName(i);
|
||||
int player_id = race_manager->getkartPlayerId(i);
|
||||
if(user_config->m_profile)
|
||||
{
|
||||
// In profile mode, load only the old kart
|
||||
@ -110,7 +112,7 @@ World::World()
|
||||
// karts can be seen.
|
||||
if(i==race_manager->getNumKarts()-1)
|
||||
{
|
||||
scene->createCamera(playerIndex, newkart);
|
||||
scene->createCamera(player_id, newkart);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -118,10 +120,9 @@ World::World()
|
||||
if (race_manager->isPlayer(i))
|
||||
{
|
||||
newkart = new PlayerKart(kart_name, position,
|
||||
&(user_config->m_player[playerIndex]),
|
||||
init_pos, playerIndex);
|
||||
m_player_karts.push_back((PlayerKart*)newkart);
|
||||
playerIndex++;
|
||||
&(user_config->m_player[player_id]),
|
||||
init_pos, player_id);
|
||||
m_player_karts[player_id] = (PlayerKart*)newkart;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -322,6 +323,10 @@ void World::updateHighscores()
|
||||
// again by a faster kart in the same race), which might be confusing
|
||||
// if we ever decide to display a message (e.g. during a race)
|
||||
unsigned int *index = new unsigned int[m_kart.size()];
|
||||
#ifdef DEBUG
|
||||
// FIXME begin: for debugging only: had a bug here once, couldn't reproduce it:
|
||||
for(unsigned int i=0; i<m_kart.size(); i++) index[i]=-1;
|
||||
#endif
|
||||
for (unsigned int i=0; i<m_kart.size(); i++ )
|
||||
{
|
||||
index[m_kart[i]->getPosition()-1] = i;
|
||||
@ -329,6 +334,19 @@ void World::updateHighscores()
|
||||
|
||||
for(unsigned int pos=0; pos<m_kart.size(); pos++)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// FIXME begin: triggered if the positions of the karts are incorrect:
|
||||
if(index[pos]<0)
|
||||
{
|
||||
fprintf(stderr, "Error, incorrect kart positions:");
|
||||
for (unsigned int i=0; i<m_kart.size(); i++ )
|
||||
{
|
||||
fprintf(stderr, "i=%d position %d\n",i, m_kart[i]->getPosition());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// FIXME: end
|
||||
|
||||
// Only record times for player karts
|
||||
if(!m_kart[index[pos]]->isPlayerKart()) continue;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user