1) Follow the leader mode now removes the first kart if

the leader is not the first.
2) AI karts brake if they are ahead of the leader
3) The leader has now the text 'leader' displayed next
   to the item.
4) The ranks in the leader results table are now correct
   (starting with 1 instead of 2)
5) Fixed two potential bugs, which might result in
   triggering an assert.
6) Replaced assert (in case that it should get triggered
   again) with useful messages to stderr.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1688 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2008-04-17 00:20:06 +00:00
parent 3612996109
commit a53ca214c5
6 changed files with 62 additions and 29 deletions

View File

@ -121,7 +121,7 @@ LeaderResult::LeaderResult()
char sTime[20];
TimeToString(race_time[i], sTime);
sprintf((char*)(m_score + MAX_STR_LEN * i), "%d. %s %d %s",
i + 1, race_manager->getKartName(position[i]).c_str(), scores[i], sTime );
i , race_manager->getKartName(position[i]).c_str(), scores[i], sTime );
widget_manager->addWgt(WTOK_FIRSTKART + i, 40, 5);
widget_manager->showWgtRect(WTOK_FIRSTKART + i);

View File

@ -381,8 +381,8 @@ void RaceGUI::drawPlayerIcons ()
glDisable(GL_CULL_FACE);
if(laps_of_leader>0 && // Display position during first lap
(world->getTime() - kart->getTimeAtLap()<5.0f ||
lap!=laps_of_leader))
(world->getTime() - kart->getTimeAtLap()<5.0f || lap!=laps_of_leader) &&
race_manager->raceHasLaps())
{ // Display for 5 seconds
char str[256];
if(position==1)
@ -398,9 +398,13 @@ void RaceGUI::drawPlayerIcons ()
str[0]='+'; str[1]=0;
TimeToString(timeBehind, str+1);
}
if(race_manager->raceHasLaps())
font_race->PrintShadow(str, 30, ICON_PLAYER_WIDHT+x, y+5,
red, green, blue);
font_race->PrintShadow(str, 30, ICON_PLAYER_WIDHT+x, y+5,
red, green, blue);
}
if(race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER && i==0)
{
font_race->PrintShadow(_("Leader"), 30, ICON_PLAYER_WIDHT+x, y+5,
255, 0, 0);
}
glEnable(GL_CULL_FACE);

View File

@ -58,7 +58,8 @@ Kart::Kart (const std::string& kart_name, int position_ ,
#endif
{
m_kart_properties = kart_properties_manager->getKart(kart_name);
m_grid_position = position_ ;
m_grid_position = position_;
m_initial_position = position_;
m_num_herrings_gobbled = 0;
m_eliminated = false;
m_finished_race = false;

View File

@ -51,14 +51,14 @@ class Smoke;
class Kart : public TerrainInfo, public Moveable
{
protected:
bool m_on_road; //true if the kart is on top of the
//road path drawn by the drivelines
bool m_on_road; // true if the kart is on top of the
// road path drawn by the drivelines
Attachment m_attachment;
Collectable m_collectable;
int m_grid_position;
int m_race_position;
int m_race_position; // current race position (1-numKarts)
int m_initial_position; // initial position of kart
KartControl m_controls; // The position of the karts controls
int m_track_sector; // index in driveline, special values
// e.g. UNKNOWN_SECTOR can be negative!
@ -142,7 +142,8 @@ public:
int getNumCollectables () const { return m_collectable.getNum();}
int getNumHerring () const { return m_num_herrings_gobbled;}
int getLap () const { return m_race_lap; }
int getPosition () const { return m_race_position ; }
int getPosition () const { return m_race_position; }
int getInitialPosition () const { return m_initial_position; }
void setFinishingState(float time);
float getFinishTime () const { return m_finish_time; }
bool raceIsFinished () const { return m_finished_race; }

View File

@ -126,6 +126,16 @@ void DefaultRobot::handle_wheelie( const int STEPS )
//-----------------------------------------------------------------------------
void DefaultRobot::handle_braking()
{
// In follow the leader mode, the kart should brake if they are ahead of
// the leader (and not the leader, i.e. don't have initial position 1)
if(race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER &&
getPosition()<world->getKart(0)->getPosition() &&
getInitialPosition()>1 )
{
printf("kart %s: braking",this->getName().c_str());
m_controls.brake = true;
return;
}
const float MIN_SPEED = world->m_track->getWidth()[m_track_sector];
//We may brake if we are about to get out of the road, but only if the

View File

@ -94,26 +94,27 @@ World::World()
loadTrack() ;
int playerIndex = 0;
for(unsigned int position=0; position<race_manager->getNumKarts(); position++)
for(unsigned int i=0; i<race_manager->getNumKarts(); i++)
{
int position = i+1; // position start with 1
sgCoord init_pos;
m_track->getStartCoords(position, &init_pos);
m_track->getStartCoords(i, &init_pos);
Kart* newkart;
const std::string& kart_name=race_manager->getKartName(position);
const std::string& kart_name=race_manager->getKartName(i);
if(user_config->m_profile)
{
// In profile mode, load only the old kart
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)
if(i==race_manager->getNumKarts()-1)
{
scene->createCamera(race_manager->getNumPlayers(), playerIndex);
}
}
else
{
if (race_manager->isPlayer(position))
if (race_manager->isPlayer(i))
{
Camera *cam = scene->createCamera(race_manager->getNumPlayers(), playerIndex);
// the given position belongs to a player
@ -130,7 +131,7 @@ World::World()
} // if !user_config->m_profile
if(user_config->m_replay_history)
{
history->LoadKartData(newkart, position);
history->LoadKartData(newkart, i);
}
newkart -> getModelTransform() -> clrTraversalMaskBits(SSGTRAV_ISECT|SSGTRAV_HOT);
@ -306,7 +307,7 @@ void World::update(float dt)
for ( Karts::size_type i = 0 ; i < m_kart.size(); ++i)
{
if(!m_kart[i]) continue; // ignore eliminated kart
if(m_kart[i]->isEliminated()) continue; // ignore eliminated kart
if(!m_kart[i]->raceIsFinished()) updateRacePosition((int)i);
if(m_kart[i]->isPlayerKart()) m_kart[i]->addMessages(); // add 'wrong direction'
}
@ -465,14 +466,30 @@ void World::updateRaceStatus(float dt)
m_leader_intervals.erase(m_leader_intervals.begin());
m_clock=m_leader_intervals[0];
int kart_number;
// If the leader kart is not the first kart, remove the first
// kart, otherwise remove the last kart.
int position_to_remove = m_kart[0]->getPosition()==1
? getCurrentNumKarts() : 1;
for (kart_number=0; kart_number<(int)m_kart.size(); kart_number++)
{
if(m_kart[kart_number]->isEliminated()) continue;
if(m_kart[kart_number]->getPosition()==getCurrentNumKarts())
if(m_kart[kart_number]->getPosition()==position_to_remove)
break;
}
assert(kart_number!=m_kart.size());
removeKart(kart_number);
if(kart_number==m_kart.size())
{
fprintf(stderr,"Problem with removing leader: position %d not found\n",
position_to_remove);
for(int i=0; i<(int)m_kart.size(); i++)
{
fprintf(stderr,"kart %d: eliminated %d position %d\n",
i,m_kart[i]->isEliminated(), m_kart[i]->getPosition());
} // for i
} // kart_number==m_kart.size()
else
{
removeKart(kart_number);
}
// The follow the leader race is over if there isonly one kart left,
// or if all players have gone
if(getCurrentNumKarts()==2 ||getCurrentNumPlayers()==0)
@ -614,12 +631,12 @@ void World::removeKart(int kart_number)
camera->setMode(Camera::CM_LEADER_MODE);
m_eliminated_players++;
}
// The kart can't be eliminated, since otherwise a race can't be restarted.
// So it's only marked to be eliminated (and ignored in all loops). Important:
// world->getCurrentNumKarts() returns the number of still racing karts. This
// value can not be used for loops over all karts, use race_manager->getNumKarts()
// instead!
projectile_manager->newExplosion(kart->getCoord());
// The kart can't be really removed from the m_kart array, since otherwise
// a race can't be restarted. So it's only marked to be eliminated (and
// ignored in all loops). Important:world->getCurrentNumKarts() returns
// the number of karts still racing. This value can not be used for loops
// over all karts, use race_manager->getNumKarts() instead!
race_manager->addKartResult(kart_number, kart->getPosition(), m_clock);
race_manager->eliminate(kart_number);
kart->eliminate();
@ -637,7 +654,7 @@ void World::updateRacePosition ( int k )
for ( Karts::size_type j = 0 ; j < m_kart.size() ; ++j )
{
if(int(j) == k) continue;
if(!m_kart[j]) continue; // eliminated karts
if(m_kart[j]->isEliminated()) continue; // eliminated karts
// Count karts ahead of the current kart, i.e. kart that are already
// finished (the current kart k has not yet finished!!), have done more