Added a new object in the world hierarchy (WorldWithRank) which

contains all codes related to ranking the karts (which is used
to display the icons in the race gui and the end result table).
The battle mode should now be fixed, but follow-the-leader
has still issues and will most likely crash at the end.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5864 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2010-09-02 13:14:07 +00:00
parent 509e8f24df
commit 3480562b78
13 changed files with 209 additions and 138 deletions

View File

@ -198,6 +198,8 @@ supertuxkart_SOURCES = \
modes/world.hpp \
modes/world_status.cpp \
modes/world_status.hpp \
modes/world_with_rank.cpp \
modes/world_with_rank.hpp \
network/character_confirm_message.hpp \
network/character_info_message.hpp \
network/character_selected_message.hpp \

View File

@ -502,6 +502,10 @@
RelativePath="..\..\modes\world_status.cpp"
>
</File>
<File
RelativePath="..\..\modes\world_with_rank.cpp"
>
</File>
</Filter>
<Filter
Name="items"
@ -1380,6 +1384,10 @@
RelativePath="..\..\modes\world_status.hpp"
>
</File>
<File
RelativePath="..\..\modes\world_with_rank.hpp"
>
</File>
</Filter>
<Filter
Name="items"

View File

@ -141,19 +141,20 @@ RaceGUIBase::KartIconDisplayInfo* FollowTheLeaderRace::getKartsDisplayInfo()
return m_kart_display_info;
}
//-----------------------------------------------------------------------------
void FollowTheLeaderRace::raceResultOrder( int* order )
void FollowTheLeaderRace::getRaceResultOrder(std::vector<int> *order)
{
const unsigned int NUM_KARTS = getNumKarts();
const unsigned int num_karts = getNumKarts();
order->resize(num_karts);
int *scores = new int[NUM_KARTS];
double *race_time = new double[NUM_KARTS];
int *scores = new int[num_karts];
double *race_time = new double[num_karts];
World *world = World::getWorld();
// Ignore kart 0, since it was the leader
order[0] = -1;
for( unsigned int kart_id = 1; kart_id < NUM_KARTS; ++kart_id )
(*order)[0] = -1;
for( unsigned int kart_id = 1; kart_id < num_karts; ++kart_id )
{
order[kart_id] = kart_id;
(*order)[kart_id] = kart_id;
scores[kart_id] = race_manager->getKartScore(kart_id);
race_time[kart_id] = race_manager->getOverallTime(kart_id);
@ -172,22 +173,25 @@ void FollowTheLeaderRace::raceResultOrder( int* order )
do
{
sorted = true;
for( unsigned int i = 1; i < NUM_KARTS - 1; ++i )
for( unsigned int i = 1; i < num_karts - 1; ++i )
{
if( scores[order[i]] < scores[order[i+1]] ||
(scores[order[i]] == scores[order[i+1]]
&& race_time[order[i]] > race_time[order[i+1]]) )
if( scores[(*order)[i]] < scores[(*order)[i+1]] ||
(scores[(*order)[i]] == scores[(*order)[i+1]]
&& race_time[(*order)[i]] > race_time[(*order)[i+1]]) )
{
int tmp = order[i];
order[i] = order[i+1];
order[i+1] = tmp;
int tmp = (*order)[i];
(*order)[i] = (*order)[i+1];
(*order)[i+1] = tmp;
sorted = false;
}
}
} while(!sorted);
for(unsigned int i=1; i<NUM_KARTS; i++)
world->getKart(order[i])->setPosition(i);
for(unsigned int i=1; i<num_karts; i++)
{
world->getKart((*order)[i])->setPosition(i);
setKartPosition((*order)[i], i);
}
delete []scores;
delete []race_time;

View File

@ -49,7 +49,7 @@ public:
/** Called by the race result GUI at the end of the race to know the final order
(fill in the 'order' array) */
virtual void raceResultOrder( int* order );
virtual void getRaceResultOrder(std::vector<int> *order);
};

View File

@ -34,7 +34,7 @@
/** Constructs the linear world. Note that here no functions can be called
* that use World::getWorld(), since it is not yet defined.
*/
LinearWorld::LinearWorld() : World()
LinearWorld::LinearWorld() : WorldWithRank()
{
m_kart_display_info = NULL;
m_last_lap_sfx = sfx_manager->createSoundSource("lastlap");
@ -48,15 +48,13 @@ LinearWorld::LinearWorld() : World()
*/
void LinearWorld::init()
{
World::init();
WorldWithRank::init();
m_last_lap_sfx_played = false;
const unsigned int kart_amount = m_karts.size();
m_position_index.resize(kart_amount);
m_kart_display_info = new RaceGUIBase::KartIconDisplayInfo[kart_amount];
for(unsigned int n=0; n<kart_amount; n++)
{
m_position_index[n] = n;
KartInfo info;
info.m_track_sector = QuadGraph::UNKNOWN_SECTOR;
info.m_last_valid_sector = 0;
@ -102,7 +100,7 @@ LinearWorld::~LinearWorld()
//-----------------------------------------------------------------------------
void LinearWorld::restartRace()
{
World::restartRace();
WorldWithRank::restartRace();
//if(m_last_lap_sfx->getStatus()== SFXManager::SFX_PLAYING)
// m_last_lap_sfx->stop();
m_last_lap_sfx_played = false;
@ -169,7 +167,7 @@ void LinearWorld::update(float delta)
{
// run generic parent stuff that applies to all modes. It
// especially updates the kart positions.
World::update(delta);
WorldWithRank::update(delta);
const unsigned int kart_amount = getNumKarts();
@ -487,60 +485,6 @@ RaceGUIBase::KartIconDisplayInfo* LinearWorld::getKartsDisplayInfo()
return m_kart_display_info;
} // getKartsDisplayInfo
// ----------------------------------------------------------------------------
/** Sets up the mapping from kart position to kart index.
*/
void LinearWorld::raceResultOrder(std::vector<int> *order)
{
const unsigned int NUM_KARTS = getNumKarts();
order->resize(NUM_KARTS);
#ifndef NDEBUG
for (unsigned int i=0; i < NUM_KARTS; i++)
{
(*order)[i] = -1;
}
bool positions_ok = true;
#endif
for (unsigned int i=0; i < NUM_KARTS; i++)
{
const int position = getKart(i)->getPosition()-1;
#ifndef NDEBUG
// sanity checks
if ((*order)[position] != -1)
{
std::cerr << "== TWO KARTS ARE BEING GIVEN THE SAME POSITION!! ==\n";
for (unsigned int j=0; j < NUM_KARTS; j++)
{
if ((*order)[j] == -1)
{
std::cout << " No kart is yet set at position " << j << std::endl;
}
else
{
std::cout << " Kart " << (*order)[j] << " is at position " << j << std::endl;
}
}
std::cout << "Kart " << i << " is being given posiiton " << (getKart(i)->getPosition()-1)
<< ", but this position is already taken\n";
positions_ok = false;
}
#endif
// actually assign the position
(*order)[position] = i; // even for eliminated karts
}
#ifndef NDEBUG
if (!positions_ok) history->Save();
assert(positions_ok);
#endif
} // raceResultOrder
//-----------------------------------------------------------------------------
/** Estimate the arrival time of any karts that haven't arrived yet by using
* their average speed up to now and the distance still to race. This
@ -746,7 +690,7 @@ void LinearWorld::updateRacePosition()
#endif
kart->setPosition(p);
m_position_index[p-1] = i;
setKartPosition(i, p);
// Switch on faster music if not already done so, if the
// first kart is doing its last lap, and if the estimated
// remaining time is less than 30 seconds.

View File

@ -20,7 +20,7 @@
#include <vector>
#include "modes/world.hpp"
#include "modes/world_with_rank.hpp"
class SFXBase;
@ -30,7 +30,7 @@ class SFXBase;
* and lap counting.
* \ingroup modes
*/
class LinearWorld : public World
class LinearWorld : public WorldWithRank
{
/** Sfx for the final lap. */
SFXBase *m_last_lap_sfx;
@ -61,9 +61,6 @@ private:
};
/** This contains a mapping from race position to kart index. */
std::vector<int> m_position_index;
protected:
RaceGUIBase::KartIconDisplayInfo* m_kart_display_info;
@ -87,8 +84,9 @@ public:
/** call just after instanciating. can't be moved to the contructor as child
classes must be instanciated, otherwise polymorphism will fail and the
results will be incorrect */
void init();
virtual void init();
virtual ~LinearWorld();
virtual void update(float delta);
int getSectorForKart(const int kart_id) const;
float getDistanceDownTrackForKart(const int kart_id) const;
@ -101,9 +99,6 @@ public:
virtual RaceGUIBase::KartIconDisplayInfo*
getKartsDisplayInfo();
virtual void moveKartAfterRescue(Kart* kart);
/** Returns the kart with position p, 1<=p<=num_karts). */
const Kart* getKartAtPosition(unsigned int p) const
{ return m_karts[m_position_index[p-1]]; }
virtual void restartRace();
virtual bool raceHasLaps(){ return true; }
@ -111,9 +106,6 @@ public:
virtual bool haveBonusBoxes(){ return true; }
/** Called by the race result GUI at the end of the race to know the final order
(fill in the 'order' array) */
virtual void raceResultOrder(std::vector<int> *order);
/** Returns true if the kart is on a valid driveline quad.
* \param kart_index Index of the kart.
*/

View File

@ -25,17 +25,17 @@
//-----------------------------------------------------------------------------
ThreeStrikesBattle::ThreeStrikesBattle() : World()
ThreeStrikesBattle::ThreeStrikesBattle() : WorldWithRank()
{
WorldStatus::setClockMode(CLOCK_CHRONO);
m_use_highscores = false;
}
} // ThreeStrikesBattle
//-----------------------------------------------------------------------------
void ThreeStrikesBattle::init()
{
World::init();
WorldWithRank::init();
// check for possible problems if AI karts were incorrectly added
if(getNumKarts() > race_manager->getNumPlayers())
@ -163,6 +163,7 @@ void ThreeStrikesBattle::updateKartRanks()
for( unsigned int n = 0; n < NUM_KARTS; ++n )
{
m_karts[ karts_list[n] ]->setPosition( n+1 );
setKartPosition(karts_list[n], n+1);
}
delete [] karts_list;
} // updateKartRank
@ -183,13 +184,13 @@ bool ThreeStrikesBattle::isRaceOver()
void ThreeStrikesBattle::terminateRace()
{
updateKartRanks();
World::terminateRace();
WorldWithRank::terminateRace();
} // terminateRace
//-----------------------------------------------------------------------------
void ThreeStrikesBattle::restartRace()
{
World::restartRace();
WorldWithRank::restartRace();
const unsigned int kart_amount = m_karts.size();
@ -319,21 +320,3 @@ void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart)
//add hit to kart
kartHit(kart->getWorldKartId());
} // moveKartAfterRescue
//-----------------------------------------------------------------------------
void ThreeStrikesBattle::raceResultOrder(std::vector<int> *order)
{
updateKartRanks();
const unsigned int num_karts = getNumKarts();
order->resize(num_karts);
for (unsigned int i=0; i < num_karts; i++) (*order)[i] = -1;
for( unsigned int kart_id = 0; kart_id < num_karts; ++kart_id )
{
const int pos = m_karts[kart_id]->getPosition() - 1;
assert(pos >= 0);
assert(pos < (int)num_karts);
(*order)[pos] = kart_id;
}
} // raceResultOrder

View File

@ -1,4 +1,4 @@
// $Id: world.hpp 2326 2008-10-04 18:50:45Z auria $
// $Id: three_strikes_battle.hpp 2326 2008-10-04 18:50:45Z auria $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004 SuperTuxKart-Team
@ -22,14 +22,14 @@
#include <string>
#include "modes/world.hpp"
#include "modes/world_with_rank.hpp"
#include "states_screens/race_gui_base.hpp"
/**
* \brief An implementation of World, to provide the 3 strikes battle game mode
* \ingroup modes
*/
class ThreeStrikesBattle : public World
class ThreeStrikesBattle : public WorldWithRank
{
private:
struct BattleInfo
@ -75,10 +75,6 @@ public:
virtual void kartHit(const int kart_id);
/** Called by the race result GUI at the end of the race to know the final order
(fill in the 'order' array) */
virtual void raceResultOrder(std::vector<int> *order);
void updateKartRanks();
}; // ThreeStrikesBattles

View File

@ -248,12 +248,6 @@ public:
*/
virtual void kartHit(const int kart_id) {};
/** Called by the race result GUI at the end of the race to know the final order
* \param[out] order returns the order of karts. order[0] will contain the ID of
* the first kart, order[1] the ID of the second kart, etc...
* Array dimension must be the number of karts.
*/
virtual void raceResultOrder(std::vector<int> *order ) = 0;
bool clearBackBuffer() const { return m_clear_back_buffer; }
const irr::video::SColor& getClearColor() const { return m_clear_color; }

View File

@ -0,0 +1,91 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Joerg Henrichs
//
// 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.
#include "modes/world_with_rank.hpp"
#include "race/history.hpp"
//-----------------------------------------------------------------------------
void WorldWithRank::init()
{
World::init();
m_position_index.resize(m_karts.size());
} // init
//-----------------------------------------------------------------------------
void WorldWithRank::setKartPosition(unsigned int kart_id,
unsigned int position)
{
m_position_index[position-1] = kart_id;
} // setKartPosition
// ----------------------------------------------------------------------------
/** Called by the race result GUI at the end of the race to know the final
* order.
* \param[out] order returns the order of karts. order[0] will contain the ID
* of the first kart, order[1] the ID of the second kart,
* etc... Array dimension will be adjusted to the number of
* karts.
*/
void WorldWithRank::getRaceResultOrder(std::vector<int> *order)
{
const unsigned int num_karts = getNumKarts();
order->resize(num_karts);
#ifndef NDEBUG
for (unsigned int i=0; i < num_karts; i++) (*order)[i] = -1;
bool positions_ok = true;
#endif
for (unsigned int i=0; i < num_karts; i++)
{
const int position = getKart(i)->getPosition()-1;
#ifndef NDEBUG
// sanity checks
if ((*order)[position] != -1)
{
std::cerr << "== TWO KARTS ARE BEING GIVEN THE SAME POSITION!! ==\n";
for (unsigned int j=0; j < num_karts; j++)
{
if ((*order)[j] == -1)
{
std::cout << " No kart is yet set at position " << j << std::endl;
}
else
{
std::cout << " Kart " << (*order)[j] << " is at position " << j << std::endl;
}
}
std::cout << "Kart " << i << " is being given posiiton " << (getKart(i)->getPosition()-1)
<< ", but this position is already taken\n";
positions_ok = false;
}
#endif
// actually assign the position
(*order)[position] = i; // even for eliminated karts
}
#ifndef NDEBUG
if (!positions_ok) history->Save();
assert(positions_ok);
#endif
} // getRaceResultOrder

56
src/modes/world_with_rank.hpp Executable file
View File

@ -0,0 +1,56 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Joerg Henrichs
//
// 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_WORLD_WITH_RANK_HPP
#define HEADER_WORLD_WITH_RANK_HPP
#include <vector>
#include "modes/world.hpp"
/**
* A WorldWithRank is a world where the karts are ranked. This is the base
* class for races and battle modes - all of which rank the kart.
* A class using this as a subclass must call setKartRank(kart id, rank)
* and this class is used to access the ranks from other objects.
* \ingroup modes
*/
class WorldWithRank : public World
{
private:
/** This contains a mapping from race position to kart index. */
std::vector<int> m_position_index;
public:
WorldWithRank() : World() {}
/** call just after instanciating. can't be moved to the contructor as child
classes must be instanciated, otherwise polymorphism will fail and the
results will be incorrect */
virtual void init();
void setKartPosition(unsigned int kart_id,
unsigned int position);
/** Returns the kart with position p, 1<=p<=num_karts). */
const Kart* getKartAtPosition(unsigned int p) const
{ return m_karts[m_position_index[p-1]]; }
/** Called by the race result GUI at the end of the race to know the
* final order (fill in the 'order' array) */
virtual void getRaceResultOrder(std::vector<int> *order);
}; // WorldWithRank
#endif

View File

@ -27,6 +27,7 @@
#include "karts/kart_properties_manager.hpp"
#include "modes/three_strikes_battle.hpp"
#include "modes/world.hpp"
#include "modes/world_with_rank.hpp"
#include "network/network_manager.hpp"
#include "race/race_manager.hpp"
#include "states_screens/feature_unlocked.hpp"
@ -106,10 +107,10 @@ RaceOverDialog::RaceOverDialog(const float percentWidth,
caption->setTabStop(false);
caption->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
World *world = World::getWorld();
WorldWithRank *world = (WorldWithRank*)World::getWorld();
const unsigned int num_karts = world->getNumKarts();
std::vector<int> order;
world->raceResultOrder(&order);
world->getRaceResultOrder(&order);
const bool display_time = (world->getClockMode() == WorldStatus::CLOCK_CHRONO);

View File

@ -23,7 +23,7 @@
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/widget.hpp"
#include "modes/world.hpp"
#include "modes/world_with_rank.hpp"
#include "states_screens/dialogs/race_over_dialog.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/race_setup_screen.hpp"
@ -215,10 +215,10 @@ void RaceResultGUI::determineTableLayout()
assert(m_font);
m_was_monospace = m_font->getMonospaceDigits();
m_font->setMonospaceDigits(true);
World *world = World::getWorld();
WorldWithRank *rank_world = (WorldWithRank*)World::getWorld();
std::vector<int> order;
world->raceResultOrder(&order);
rank_world->getRaceResultOrder(&order);
m_all_row_infos.resize(order.size());
@ -239,7 +239,7 @@ void RaceResultGUI::determineTableLayout()
// Save a pointer to the current row_info entry
RowInfo *ri = &(m_all_row_infos[num_karts]);
num_karts++;
Kart *kart = world->getKart(order[i]);
Kart *kart = rank_world->getKart(order[i]);
ri->m_is_player_kart = kart->getController()->isPlayerController();
ri->m_kart_name = kart->getName();