diff --git a/src/Makefile.am b/src/Makefile.am
index 58e02d9d4..2ad7a67fb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -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 \
diff --git a/src/ide/vc9/supertuxkart.vcproj b/src/ide/vc9/supertuxkart.vcproj
index 0ec6fa047..a4ffec1b5 100644
--- a/src/ide/vc9/supertuxkart.vcproj
+++ b/src/ide/vc9/supertuxkart.vcproj
@@ -502,6 +502,10 @@
RelativePath="..\..\modes\world_status.cpp"
>
+
+
+
+
*order)
{
- const unsigned int NUM_KARTS = getNumKarts();
-
- int *scores = new int[NUM_KARTS];
- double *race_time = new double[NUM_KARTS];
+ const unsigned int num_karts = getNumKarts();
+ order->resize(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;
- sorted = false;
+ int tmp = (*order)[i];
+ (*order)[i] = (*order)[i+1];
+ (*order)[i+1] = tmp;
+ sorted = false;
}
}
} while(!sorted);
- for(unsigned int i=1; igetKart(order[i])->setPosition(i);
+ for(unsigned int i=1; igetKart((*order)[i])->setPosition(i);
+ setKartPosition((*order)[i], i);
+ }
delete []scores;
delete []race_time;
diff --git a/src/modes/follow_the_leader.hpp b/src/modes/follow_the_leader.hpp
index 9903225c8..0cfd4d25f 100644
--- a/src/modes/follow_the_leader.hpp
+++ b/src/modes/follow_the_leader.hpp
@@ -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 *order);
};
diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp
index 5701863e9..f71f50281 100644
--- a/src/modes/linear_world.cpp
+++ b/src/modes/linear_world.cpp
@@ -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; ngetStatus()== 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 *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.
diff --git a/src/modes/linear_world.hpp b/src/modes/linear_world.hpp
index c2be872f6..db574e9e7 100644
--- a/src/modes/linear_world.hpp
+++ b/src/modes/linear_world.hpp
@@ -20,7 +20,7 @@
#include
-#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 m_position_index;
-
protected:
RaceGUIBase::KartIconDisplayInfo* m_kart_display_info;
@@ -84,11 +81,12 @@ protected:
public:
LinearWorld();
- /** 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();
+ /** 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();
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 *order);
/** Returns true if the kart is on a valid driveline quad.
* \param kart_index Index of the kart.
*/
diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp
index 650c0900c..ce398b9f0 100644
--- a/src/modes/three_strikes_battle.cpp
+++ b/src/modes/three_strikes_battle.cpp
@@ -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 *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
diff --git a/src/modes/three_strikes_battle.hpp b/src/modes/three_strikes_battle.hpp
index 923de376e..3b71b7a38 100644
--- a/src/modes/three_strikes_battle.hpp
+++ b/src/modes/three_strikes_battle.hpp
@@ -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
-#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
@@ -74,11 +74,7 @@ public:
virtual std::string getIdent() const;
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 *order);
-
+
void updateKartRanks();
}; // ThreeStrikesBattles
diff --git a/src/modes/world.hpp b/src/modes/world.hpp
index 530d4e9fe..09f8aacd3 100644
--- a/src/modes/world.hpp
+++ b/src/modes/world.hpp
@@ -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 *order ) = 0;
bool clearBackBuffer() const { return m_clear_back_buffer; }
const irr::video::SColor& getClearColor() const { return m_clear_color; }
diff --git a/src/modes/world_with_rank.cpp b/src/modes/world_with_rank.cpp
new file mode 100644
index 000000000..f98f2b72e
--- /dev/null
+++ b/src/modes/world_with_rank.cpp
@@ -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 *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
+
diff --git a/src/modes/world_with_rank.hpp b/src/modes/world_with_rank.hpp
new file mode 100755
index 000000000..12539db4c
--- /dev/null
+++ b/src/modes/world_with_rank.hpp
@@ -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
+
+#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 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 *order);
+}; // WorldWithRank
+
+#endif
diff --git a/src/states_screens/dialogs/race_over_dialog.cpp b/src/states_screens/dialogs/race_over_dialog.cpp
index 45e922fa0..02b4db0c0 100644
--- a/src/states_screens/dialogs/race_over_dialog.cpp
+++ b/src/states_screens/dialogs/race_over_dialog.cpp
@@ -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 order;
- world->raceResultOrder(&order);
+ world->getRaceResultOrder(&order);
const bool display_time = (world->getClockMode() == WorldStatus::CLOCK_CHRONO);
diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp
index ddd3a961f..5cf8bc17e 100644
--- a/src/states_screens/race_result_gui.cpp
+++ b/src/states_screens/race_result_gui.cpp
@@ -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 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();