From 7799e9835dfc056df5bf4a2ddd747e5bf638bdbd Mon Sep 17 00:00:00 2001 From: hiker <henrichsjoerg@gmail.com> Date: Thu, 30 Jul 2015 17:12:48 +1000 Subject: [PATCH 1/8] Added a getStartTransform function to World. Use this to change the start position of the non-leader karts in a FTL race, so that those karts now start at the end of all start positions, and not directly behind the leader. --- src/modes/cutscene_world.cpp | 5 ----- src/modes/follow_the_leader.cpp | 14 +++++++++++++- src/modes/follow_the_leader.hpp | 9 +++++++-- src/modes/profile_world.cpp | 2 +- src/modes/soccer_world.cpp | 6 +++--- src/modes/three_strikes_battle.cpp | 2 +- src/modes/world.cpp | 12 ++++++++++-- src/modes/world.hpp | 1 + src/modes/world_with_rank.cpp | 2 +- src/tracks/track.cpp | 9 ++++++++- src/tracks/track.hpp | 2 +- 11 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/modes/cutscene_world.cpp b/src/modes/cutscene_world.cpp index a10ec95af..e3f12e79d 100644 --- a/src/modes/cutscene_world.cpp +++ b/src/modes/cutscene_world.cpp @@ -77,13 +77,8 @@ void CutsceneWorld::init() m_duration = -1.0f; - //const btTransform &s = getTrack()->getStartTransform(0); - //const Vec3 &v = s.getOrigin(); Camera* stk_cam = Camera::createCamera(NULL); m_camera = stk_cam->getCameraSceneNode(); - //m_camera = irr_driver->getSceneManager() - // ->addCameraSceneNode(NULL, core::vector3df(0.0f, 0.0f, 0.0f), - // core::vector3df(0.0f, 0.0f, 0.0f)); m_camera->setFOV(0.61f); m_camera->bindTargetAndRotation(true); // no "look-at" diff --git a/src/modes/follow_the_leader.cpp b/src/modes/follow_the_leader.cpp index 00ca1e942..7b29a8653 100644 --- a/src/modes/follow_the_leader.cpp +++ b/src/modes/follow_the_leader.cpp @@ -101,11 +101,23 @@ int FollowTheLeaderRace::getScoreForPosition(int p) return m_score_for_position[p - 2]; } // getScoreForPosition +//----------------------------------------------------------------------------- +const btTransform &FollowTheLeaderRace::getStartTransform(int index) +{ + if (index == 0) // Leader start position + return m_track->getStartTransform(index); + + // Otherwise the karts will start at the rear starting positions + int start_index = stk_config->m_max_karts + - race_manager->getNumberOfKarts() + index; + return m_track->getStartTransform(start_index); +} // getStartTransform + //----------------------------------------------------------------------------- /** Returns the original time at which the countdown timer started. This is * used by the race_gui to display the music credits in FTL mode correctly. */ -float FollowTheLeaderRace::getClockStartTime() +float FollowTheLeaderRace::getClockStartTime() const { return m_leader_intervals[0]; } // getClockStartTime diff --git a/src/modes/follow_the_leader.hpp b/src/modes/follow_the_leader.hpp index 939f54129..da5fe1f6d 100644 --- a/src/modes/follow_the_leader.hpp +++ b/src/modes/follow_the_leader.hpp @@ -48,14 +48,19 @@ public: // overriding World methods virtual void reset() OVERRIDE; virtual const std::string& getIdent() const OVERRIDE; - virtual float getClockStartTime(); - virtual bool useFastMusicNearEnd() const OVERRIDE { return false; } + virtual const btTransform &getStartTransform(int index); + virtual float getClockStartTime() const; virtual void getKartsDisplayInfo( std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE; virtual void init() OVERRIDE; virtual void terminateRace() OVERRIDE; virtual bool isRaceOver() OVERRIDE; + // ------------------------------------------------------------------------ + /** Returns if this type of race has laps. */ virtual bool raceHasLaps() OVERRIDE { return false; } + // ------------------------------------------------------------------------ + /** Returns if faster music should be used at the end. */ + virtual bool useFastMusicNearEnd() const OVERRIDE { return false; } }; // FollowTheLeader diff --git a/src/modes/profile_world.cpp b/src/modes/profile_world.cpp index 0fef5edc7..7015a7b13 100644 --- a/src/modes/profile_world.cpp +++ b/src/modes/profile_world.cpp @@ -108,7 +108,7 @@ AbstractKart *ProfileWorld::createKart(const std::string &kart_ident, int index, RaceManager::KartType type, const PlayerDifficulty *difficulty) { - btTransform init_pos = m_track->getStartTransform(index); + btTransform init_pos = getStartTransform(index); Kart *new_kart = new KartWithStats(kart_ident, /*world kart id*/ index, diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index dcba80e8c..0fc8f553c 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -336,7 +336,7 @@ void SoccerWorld::moveKartAfterRescue(AbstractKart* kart) { // no need for the overhead to compute exact distance with sqrt(), // so using the 'manhattan' heuristic which will do fine enough. - const btTransform &s = world->getTrack()->getStartTransform(n); + const btTransform &s = getStartTransform(n); const Vec3 &v=s.getOrigin(); float accumulatedDistance = .0f; bool spawnPointClear = true; @@ -368,7 +368,7 @@ void SoccerWorld::moveKartAfterRescue(AbstractKart* kart) } assert(furthest_id_found != -1); - const btTransform &s = world->getTrack()->getStartTransform(furthest_id_found); + const btTransform &s = getStartTransform(furthest_id_found); const Vec3 &xyz = s.getOrigin(); kart->setXYZ(xyz); kart->setRotation(s.getRotation()); @@ -481,7 +481,7 @@ AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index, if(index % 2 != 0) posIndex += 1; } - btTransform init_pos = m_track->getStartTransform(posIndex); + btTransform init_pos = getStartTransform(posIndex); AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos, difficulty); diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp index aa95da191..d24555bf8 100644 --- a/src/modes/three_strikes_battle.cpp +++ b/src/modes/three_strikes_battle.cpp @@ -497,7 +497,7 @@ unsigned int ThreeStrikesBattle::getRescuePositionIndex(AbstractKart *kart) for(int n=0; n<start_spots_amount; n++) { - const btTransform &s = getTrack()->getStartTransform(n); + const btTransform &s = getStartTransform(n); const Vec3 &v=s.getOrigin(); float accumulated_distance = .0f; bool spawn_point_clear = true; diff --git a/src/modes/world.cpp b/src/modes/world.cpp index f636fe2f2..4224b1763 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -305,9 +305,9 @@ AbstractKart *World::createKart(const std::string &kart_ident, int index, const PlayerDifficulty *difficulty) { int position = index+1; - btTransform init_pos = m_track->getStartTransform(index); + btTransform init_pos = getStartTransform(index); AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos, - difficulty); + difficulty); new_kart->init(race_manager->getKartType(index)); Controller *controller = NULL; switch(kart_type) @@ -337,6 +337,14 @@ AbstractKart *World::createKart(const std::string &kart_ident, int index, return new_kart; } // createKart +//----------------------------------------------------------------------------- +/** Returns the start coordinates for a kart with a given index. + * \param index Index of kart ranging from 0 to kart_num-1. */ +const btTransform &World::getStartTransform(int index) +{ + return m_track->getStartTransform(index); +} // getStartTransform + //----------------------------------------------------------------------------- /** Creates an AI controller for the kart. * \param kart The kart to be controlled by an AI. diff --git a/src/modes/world.hpp b/src/modes/world.hpp index fef41591b..94c6ccb39 100644 --- a/src/modes/world.hpp +++ b/src/modes/world.hpp @@ -294,6 +294,7 @@ public: PhysicalObject *object); AbstractKart* getPlayerKart(unsigned int player) const; AbstractKart* getLocalPlayerKart(unsigned int n) const; + virtual const btTransform &getStartTransform(int index); // ------------------------------------------------------------------------ /** Returns a pointer to the race gui. */ RaceGUIBase *getRaceGUI() const { return m_race_gui;} diff --git a/src/modes/world_with_rank.cpp b/src/modes/world_with_rank.cpp index e34a4fe91..9482d1f95 100644 --- a/src/modes/world_with_rank.cpp +++ b/src/modes/world_with_rank.cpp @@ -149,7 +149,7 @@ unsigned int WorldWithRank::getRescuePositionIndex(AbstractKart *kart) for (int n=0; n<start_spots_amount; n++) { - const btTransform &s = getTrack()->getStartTransform(n); + const btTransform &s = getStartTransform(n); const Vec3 &v = s.getOrigin(); float abs_distance = (v - kart->getXYZ()).length(); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 89b3aa614..9880be647 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1736,7 +1736,14 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) if (!m_is_arena && !m_is_soccer && !m_is_cutscene) { - m_start_transforms.resize(race_manager->getNumberOfKarts()); + if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_FOLLOW_LEADER) + { + // In a FTL race the non-leader karts are placed at the end of the + // field, so we need all start positions. + m_start_transforms.resize(stk_config->m_max_karts); + } + else + m_start_transforms.resize(race_manager->getNumberOfKarts()); QuadGraph::get()->setDefaultStartPositions(&m_start_transforms, karts_per_row, forwards_distance, diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 23b88e997..5ac4daa79 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -523,7 +523,7 @@ public: // ------------------------------------------------------------------------ /** Returns the start coordinates for a kart with a given index. * \param index Index of kart ranging from 0 to kart_num-1. */ - btTransform getStartTransform (unsigned int index) const + const btTransform& getStartTransform (unsigned int index) const { if (index >= m_start_transforms.size()) Log::fatal("Track", "No start position for kart %i.", index); From bf858dd3ff84c43fde59b2aa5055e75257f871bb Mon Sep 17 00:00:00 2001 From: hiker <henrichsjoerg@gmail.com> Date: Thu, 30 Jul 2015 17:14:18 +1000 Subject: [PATCH 2/8] Fixed compiler warning. --- src/guiengine/widgets/icon_button_widget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guiengine/widgets/icon_button_widget.cpp b/src/guiengine/widgets/icon_button_widget.cpp index 587527738..9093ec7e6 100644 --- a/src/guiengine/widgets/icon_button_widget.cpp +++ b/src/guiengine/widgets/icon_button_widget.cpp @@ -182,7 +182,7 @@ void IconButtonWidget::add() x1 += diff; x2 += diff; } - else if (x2 > irr_driver->getActualScreenSize().Width) + else if (x2 > (int)irr_driver->getActualScreenSize().Width) { int diff = x2 - irr_driver->getActualScreenSize().Width; x2 -= diff; From a9761e30da60abc1576182cf9863f480c23106e8 Mon Sep 17 00:00:00 2001 From: Tobias Markus <tobbi.bugs@googlemail.com> Date: Thu, 30 Jul 2015 18:46:01 +0200 Subject: [PATCH 3/8] Fix various issues reported by coverity --- src/states_screens/options_screen_audio.cpp | 3 ++- src/states_screens/options_screen_input.cpp | 3 ++- src/states_screens/options_screen_input2.cpp | 4 ++-- src/states_screens/options_screen_ui.cpp | 3 ++- src/states_screens/options_screen_video.cpp | 3 ++- src/states_screens/user_screen.cpp | 3 ++- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/states_screens/options_screen_audio.cpp b/src/states_screens/options_screen_audio.cpp index 734c12a2d..799bab896 100644 --- a/src/states_screens/options_screen_audio.cpp +++ b/src/states_screens/options_screen_audio.cpp @@ -59,7 +59,8 @@ void OptionsScreenAudio::init() { Screen::init(); RibbonWidget* ribbon = this->getWidget<RibbonWidget>("options_choice"); - if (ribbon != NULL) ribbon->select( "tab_audio", PLAYER_ID_GAME_MASTER ); + assert(ribbon != NULL); + ribbon->select( "tab_audio", PLAYER_ID_GAME_MASTER ); ribbon->getRibbonChildren()[0].setTooltip( _("Graphics") ); ribbon->getRibbonChildren()[2].setTooltip( _("User Interface") ); diff --git a/src/states_screens/options_screen_input.cpp b/src/states_screens/options_screen_input.cpp index 98aec63d1..7b8e970b6 100644 --- a/src/states_screens/options_screen_input.cpp +++ b/src/states_screens/options_screen_input.cpp @@ -133,7 +133,8 @@ void OptionsScreenInput::init() { Screen::init(); RibbonWidget* tabBar = this->getWidget<RibbonWidget>("options_choice"); - if (tabBar != NULL) tabBar->select( "tab_controls", PLAYER_ID_GAME_MASTER ); + assert(tabBar != NULL); + tabBar->select( "tab_controls", PLAYER_ID_GAME_MASTER ); tabBar->getRibbonChildren()[0].setTooltip( _("Graphics") ); tabBar->getRibbonChildren()[1].setTooltip( _("Audio") ); diff --git a/src/states_screens/options_screen_input2.cpp b/src/states_screens/options_screen_input2.cpp index 3832765d2..363860e07 100644 --- a/src/states_screens/options_screen_input2.cpp +++ b/src/states_screens/options_screen_input2.cpp @@ -79,8 +79,8 @@ void OptionsScreenInput2::init() { Screen::init(); RibbonWidget* tabBar = getWidget<RibbonWidget>("options_choice"); - if (tabBar != NULL) tabBar->select( "tab_controls", - PLAYER_ID_GAME_MASTER ); + assert(tabBar != NULL); + tabBar->select( "tab_controls", PLAYER_ID_GAME_MASTER ); tabBar->getRibbonChildren()[0].setTooltip( _("Graphics") ); tabBar->getRibbonChildren()[1].setTooltip( _("Audio") ); diff --git a/src/states_screens/options_screen_ui.cpp b/src/states_screens/options_screen_ui.cpp index 2358035d4..8d301eeaf 100644 --- a/src/states_screens/options_screen_ui.cpp +++ b/src/states_screens/options_screen_ui.cpp @@ -112,7 +112,8 @@ void OptionsScreenUI::init() { Screen::init(); RibbonWidget* ribbon = getWidget<RibbonWidget>("options_choice"); - if (ribbon != NULL) ribbon->select( "tab_ui", PLAYER_ID_GAME_MASTER ); + assert(ribbon != NULL); + ribbon->select( "tab_ui", PLAYER_ID_GAME_MASTER ); ribbon->getRibbonChildren()[0].setTooltip( _("Graphics") ); ribbon->getRibbonChildren()[1].setTooltip( _("Audio") ); diff --git a/src/states_screens/options_screen_video.cpp b/src/states_screens/options_screen_video.cpp index 5981a9cce..6939a9e15 100644 --- a/src/states_screens/options_screen_video.cpp +++ b/src/states_screens/options_screen_video.cpp @@ -159,7 +159,8 @@ void OptionsScreenVideo::init() { Screen::init(); RibbonWidget* ribbon = getWidget<RibbonWidget>("options_choice"); - if (ribbon != NULL) ribbon->select( "tab_video", PLAYER_ID_GAME_MASTER ); + assert(ribbon != NULL); + ribbon->select( "tab_video", PLAYER_ID_GAME_MASTER ); ribbon->getRibbonChildren()[1].setTooltip( _("Audio") ); ribbon->getRibbonChildren()[2].setTooltip( _("User Interface") ); diff --git a/src/states_screens/user_screen.cpp b/src/states_screens/user_screen.cpp index 7c7e7d3c0..64e846f4f 100644 --- a/src/states_screens/user_screen.cpp +++ b/src/states_screens/user_screen.cpp @@ -631,7 +631,8 @@ void BaseUserScreen::unloaded() void TabbedUserScreen::init() { RibbonWidget* tab_bar = getWidget<RibbonWidget>("options_choice"); - if (tab_bar) tab_bar->select("tab_players", PLAYER_ID_GAME_MASTER); + assert(tab_bar != NULL); + tab_bar->select("tab_players", PLAYER_ID_GAME_MASTER); tab_bar->getRibbonChildren()[0].setTooltip( _("Graphics") ); tab_bar->getRibbonChildren()[1].setTooltip( _("Audio") ); tab_bar->getRibbonChildren()[2].setTooltip( _("User Interface") ); From 25c1880c183c0cb18ef4ae5bad7014e1a5d3f333 Mon Sep 17 00:00:00 2001 From: hiker <henrichsjoerg@gmail.com> Date: Fri, 31 Jul 2015 07:49:54 +1000 Subject: [PATCH 4/8] Fixed rescue in soccer mode (which would previously used World's moveKartAfterRescue, not its own custom function). --- src/modes/world.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modes/world.hpp b/src/modes/world.hpp index 94c6ccb39..69e5bf538 100644 --- a/src/modes/world.hpp +++ b/src/modes/world.hpp @@ -231,7 +231,7 @@ public: /** Returns the bullet transformation for the specified rescue index. */ virtual btTransform getRescueTransform(unsigned int index) const = 0; // ------------------------------------------------------------------------ - void moveKartAfterRescue(AbstractKart* kart); + virtual void moveKartAfterRescue(AbstractKart* kart); // ------------------------------------------------------------------------ /** Called when it is needed to know whether this kind of race involves * counting laps. */ From 431853b451ee8e91ab6c207cd476509b6835957f Mon Sep 17 00:00:00 2001 From: hiker <henrichsjoerg@gmail.com> Date: Fri, 31 Jul 2015 15:45:25 +1000 Subject: [PATCH 5/8] Removed some unused code, added better error message in case stk_config.xml could not be found. --- src/io/file_manager.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index ef193ae13..1ddf9271c 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -181,14 +181,22 @@ FileManager::FileManager() { #ifdef SUPERTUXKART_DATADIR root_dir = SUPERTUXKART_DATADIR"/data/"; - if(root_dir.size()==0 || root_dir[root_dir.size()-1]!='/') - root_dir+='/'; - #else root_dir = "/usr/local/share/games/supertuxkart/"; #endif } + if (!m_file_system->existFile((root_dir + "stk_config.xml").c_str())) + { + Log::error("FileManager", "Could not file stk_config.xml in any " + "standard location (esp. ../data)."); + Log::error("FileManager", + "Last location checked '%s'.", root_dir.c_str()); + Log::fatal("FileManager", + "Set $SUPERTUXKART_DATADIR to point to the data directory."); + // fatal will exit the application + } + addRootDirs(root_dir); if( fileExists(root_dir+"../../stk-assets")) addRootDirs(root_dir+"../../stk-assets"); From a81366c4140ec5610c9d8fbfaf4b1b23720980e5 Mon Sep 17 00:00:00 2001 From: hiker <henrichsjoerg@gmail.com> Date: Fri, 31 Jul 2015 16:27:52 +1000 Subject: [PATCH 6/8] Removed rescue-code duplication in battle mode and soccer mode. --- src/modes/overworld.cpp | 31 +++++++++++ src/modes/overworld.hpp | 1 + src/modes/soccer_world.cpp | 82 ------------------------------ src/modes/soccer_world.hpp | 3 +- src/modes/three_strikes_battle.cpp | 50 ------------------ src/modes/three_strikes_battle.hpp | 1 - src/modes/world_with_rank.cpp | 51 +++++++++++++------ 7 files changed, 68 insertions(+), 151 deletions(-) diff --git a/src/modes/overworld.cpp b/src/modes/overworld.cpp index 0f5166caa..ba7e7df2d 100644 --- a/src/modes/overworld.cpp +++ b/src/modes/overworld.cpp @@ -160,6 +160,37 @@ void OverWorld::update(float dt) } } // update +// ---------------------------------------------------------------------------- +/** Finds the starting position which is closest to the kart. + * \param kart The kart for which a rescue position needs to be determined. + */ +unsigned int OverWorld::getRescuePositionIndex(AbstractKart *kart) +{ + // find closest point to drop kart on + const int start_spots_amount = getNumberOfRescuePositions(); + assert(start_spots_amount > 0); + + int closest_id = -1; + float closest_distance = 999999999.0f; + + for (int n=0; n<start_spots_amount; n++) + { + const btTransform &s = getStartTransform(n); + const Vec3 &v = s.getOrigin(); + + float abs_distance = (v - kart->getXYZ()).length(); + + if (abs_distance < closest_distance) + { + closest_distance = abs_distance; + closest_id = n; + } + } + + assert(closest_id != -1); + return closest_id; +} // getRescuePositionIndex + //----------------------------------------------------------------------------- /** This function is not used in the overworld race gui. */ diff --git a/src/modes/overworld.hpp b/src/modes/overworld.hpp index 4001f0faa..62d510994 100644 --- a/src/modes/overworld.hpp +++ b/src/modes/overworld.hpp @@ -48,6 +48,7 @@ public: static void enterOverWorld(); virtual void update(float delta) OVERRIDE; + unsigned int getRescuePositionIndex(AbstractKart *kart) OVERRIDE; virtual void getKartsDisplayInfo( std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE; // ------------------------------------------------------------------------ diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 0fc8f553c..2b18d14f6 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -315,88 +315,6 @@ void SoccerWorld::getKartsDisplayInfo( */ } // getKartsDisplayInfo -//----------------------------------------------------------------------------- -/** Moves a kart to its rescue position. - * \param kart The kart that was rescued. - */ -void SoccerWorld::moveKartAfterRescue(AbstractKart* kart) -{ - // find closest point to drop kart on - World *world = World::getWorld(); - const int start_spots_amount = world->getTrack()->getNumberOfStartPositions(); - assert(start_spots_amount > 0); - - float largest_accumulated_distance_found = -1; - int furthest_id_found = -1; - - const float kart_x = kart->getXYZ().getX(); - const float kart_z = kart->getXYZ().getZ(); - - for(int n=0; n<start_spots_amount; n++) - { - // no need for the overhead to compute exact distance with sqrt(), - // so using the 'manhattan' heuristic which will do fine enough. - const btTransform &s = getStartTransform(n); - const Vec3 &v=s.getOrigin(); - float accumulatedDistance = .0f; - bool spawnPointClear = true; - - for(unsigned int k=0; k<getCurrentNumKarts(); k++) - { - const AbstractKart *currentKart = World::getWorld()->getKart(k); - const float currentKart_x = currentKart->getXYZ().getX(); - const float currentKartk_z = currentKart->getXYZ().getZ(); - - if(kart_x!=currentKart_x && kart_z !=currentKartk_z) - { - float absDistance = fabs(currentKart_x - v.getX()) + - fabs(currentKartk_z - v.getZ()); - if(absDistance < CLEAR_SPAWN_RANGE) - { - spawnPointClear = false; - break; - } - accumulatedDistance += absDistance; - } - } - - if(largest_accumulated_distance_found < accumulatedDistance && spawnPointClear) - { - furthest_id_found = n; - largest_accumulated_distance_found = accumulatedDistance; - } - } - - assert(furthest_id_found != -1); - const btTransform &s = getStartTransform(furthest_id_found); - const Vec3 &xyz = s.getOrigin(); - kart->setXYZ(xyz); - kart->setRotation(s.getRotation()); - - //position kart from same height as in World::resetAllKarts - btTransform pos; - pos.setOrigin(kart->getXYZ()+btVector3(0, 0.5f*kart->getKartHeight(), 0.0f)); - pos.setRotation( btQuaternion(btVector3(0.0f, 1.0f, 0.0f), 0 /* angle */) ); - - kart->getBody()->setCenterOfMassTransform(pos); - - //project kart to surface of track - bool kart_over_ground = m_track->findGround(kart); - - if (kart_over_ground) - { - //add vertical offset so that the kart starts off above the track - float vertical_offset = kart->getKartProperties()->getVertRescueOffset() * - kart->getKartHeight(); - kart->getBody()->translate(btVector3(0, vertical_offset, 0)); - } - else - { - Log::warn("[SoccerWorld]", " Invalid position after rescue for kart %s on track %s.", - kart->getIdent().c_str(), m_track->getIdent().c_str()); - } -} // moveKartAfterRescue - //----------------------------------------------------------------------------- /** Set position and team for the karts */ void SoccerWorld::initKartList() diff --git a/src/modes/soccer_world.hpp b/src/modes/soccer_world.hpp index d33f1dd74..8d896d47c 100644 --- a/src/modes/soccer_world.hpp +++ b/src/modes/soccer_world.hpp @@ -76,8 +76,7 @@ public: virtual void getKartsDisplayInfo( std::vector<RaceGUIBase::KartIconDisplayInfo> *info); int getScore(unsigned int i); - virtual bool raceHasLaps(){ return false; } - virtual void moveKartAfterRescue(AbstractKart* kart); + virtual bool raceHasLaps() { return false; } virtual const std::string& getIdent() const; diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp index d24555bf8..6fa48f882 100644 --- a/src/modes/three_strikes_battle.cpp +++ b/src/modes/three_strikes_battle.cpp @@ -477,53 +477,3 @@ void ThreeStrikesBattle::getKartsDisplayInfo( } } // getKartsDisplayInfo -//----------------------------------------------------------------------------- -/** Determines the rescue position for a kart. The rescue position is the - * start position which is has the biggest accumulated distance to all other - * karts, and which has no other kart very close. The latter avoids dropping - * a kart on top of another kart. - * \param kart The kart that is going to be rescued. - * \returns The index of the start position to which the rescued kart - * should be moved to. - */ - -unsigned int ThreeStrikesBattle::getRescuePositionIndex(AbstractKart *kart) -{ - const int start_spots_amount = getTrack()->getNumberOfStartPositions(); - assert(start_spots_amount > 0); - - float largest_accumulated_distance_found = -1; - int furthest_id_found = -1; - - for(int n=0; n<start_spots_amount; n++) - { - const btTransform &s = getStartTransform(n); - const Vec3 &v=s.getOrigin(); - float accumulated_distance = .0f; - bool spawn_point_clear = true; - - for(unsigned int k=0; k<getCurrentNumKarts(); k++) - { - if(kart->getWorldKartId()==k) continue; - float abs_distance2 = (getKart(k)->getXYZ()-v).length2_2d(); - const float CLEAR_SPAWN_RANGE2 = 5*5; - if( abs_distance2 < CLEAR_SPAWN_RANGE2) - { - spawn_point_clear = false; - break; - } - accumulated_distance += sqrt(abs_distance2); - } - - if(accumulated_distance > largest_accumulated_distance_found && - spawn_point_clear) - { - furthest_id_found = n; - largest_accumulated_distance_found = accumulated_distance; - } - } - - assert(furthest_id_found != -1); - return furthest_id_found; -} // getRescuePositionIndex - diff --git a/src/modes/three_strikes_battle.hpp b/src/modes/three_strikes_battle.hpp index 46a18674c..fe09b9340 100644 --- a/src/modes/three_strikes_battle.hpp +++ b/src/modes/three_strikes_battle.hpp @@ -97,7 +97,6 @@ public: virtual void getKartsDisplayInfo( std::vector<RaceGUIBase::KartIconDisplayInfo> *info); virtual bool raceHasLaps(){ return false; } - virtual unsigned int getRescuePositionIndex(AbstractKart *kart); virtual const std::string& getIdent() const; diff --git a/src/modes/world_with_rank.cpp b/src/modes/world_with_rank.cpp index 9482d1f95..f24ef58c3 100644 --- a/src/modes/world_with_rank.cpp +++ b/src/modes/world_with_rank.cpp @@ -134,35 +134,54 @@ unsigned int WorldWithRank::getNumberOfRescuePositions() const return getTrack()->getNumberOfStartPositions(); } // getNumberOfRescuePositions -// ---------------------------------------------------------------------------- -/** Finds the starting position which is closest to the kart. - * \param kart The kart for which a rescue position needs to be determined. +//----------------------------------------------------------------------------- +/** Determines the rescue position for a kart. The rescue position is the + * start position which is has the biggest accumulated distance to all other + * karts, and which has no other kart very close. The latter avoids dropping + * a kart on top of another kart. This is the method used + * \param kart The kart that is going to be rescued. + * \returns The index of the start position to which the rescued kart + * should be moved to. */ + unsigned int WorldWithRank::getRescuePositionIndex(AbstractKart *kart) { - // find closest point to drop kart on - const int start_spots_amount = getNumberOfRescuePositions(); + const int start_spots_amount = getTrack()->getNumberOfStartPositions(); assert(start_spots_amount > 0); - int closest_id = -1; - float closest_distance = 999999999.0f; + float largest_accumulated_distance_found = -1; + int furthest_id_found = -1; - for (int n=0; n<start_spots_amount; n++) + for(int n=0; n<start_spots_amount; n++) { const btTransform &s = getStartTransform(n); - const Vec3 &v = s.getOrigin(); + const Vec3 &v=s.getOrigin(); + float accumulated_distance = .0f; + bool spawn_point_clear = true; - float abs_distance = (v - kart->getXYZ()).length(); - - if (abs_distance < closest_distance) + for(unsigned int k=0; k<getCurrentNumKarts(); k++) { - closest_distance = abs_distance; - closest_id = n; + if(kart->getWorldKartId()==k) continue; + float abs_distance2 = (getKart(k)->getXYZ()-v).length2_2d(); + const float CLEAR_SPAWN_RANGE2 = 5*5; + if( abs_distance2 < CLEAR_SPAWN_RANGE2) + { + spawn_point_clear = false; + break; + } + accumulated_distance += sqrt(abs_distance2); + } + + if(accumulated_distance > largest_accumulated_distance_found && + spawn_point_clear) + { + furthest_id_found = n; + largest_accumulated_distance_found = accumulated_distance; } } - assert(closest_id != -1); - return closest_id; + assert(furthest_id_found != -1); + return furthest_id_found; } // getRescuePositionIndex // ---------------------------------------------------------------------------- From 78c592e4e5b816d02afea137e7f4021fd852db1e Mon Sep 17 00:00:00 2001 From: hiker <henrichsjoerg@gmail.com> Date: Fri, 31 Jul 2015 22:06:21 +1000 Subject: [PATCH 7/8] Added a file with a 'unique filename' with version number which is used by STK to detect that stk is reading the right data files (and therefore avoids #2073, in which stk finds the wrong data directory). --- data/supertuxkart.git | 2 ++ src/io/file_manager.cpp | 29 ++++++++++++++++------------- src/io/file_manager.hpp | 8 ++++++++ src/main.cpp | 2 +- 4 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 data/supertuxkart.git diff --git a/data/supertuxkart.git b/data/supertuxkart.git new file mode 100644 index 000000000..b37a12b9c --- /dev/null +++ b/data/supertuxkart.git @@ -0,0 +1,2 @@ +This file is only here to help STK finding the right directory, +and to avoid problems with other directories called 'data'. diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index 1ddf9271c..e969b87b9 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -142,7 +142,7 @@ FileManager::FileManager() m_file_system = irr::io::createFileSystem(); - irr::io::path exe_path; + std::string exe_path; // Search for the root directory // ============================= @@ -151,8 +151,11 @@ FileManager::FileManager() // This is esp. useful for Visual Studio, since it's not necessary // to define the working directory when debugging, it works automatically. std::string root_dir; - if(m_file_system->existFile(CommandLine::getExecName().c_str())) - exe_path = m_file_system->getFileDir(CommandLine::getExecName().c_str()); + const std::string version = std::string("supertuxkart.") + STK_VERSION; + if (fileExists(CommandLine::getExecName())) + { + exe_path = StringUtils::getPath(CommandLine::getExecName()); + } if(exe_path.size()==0 || exe_path[exe_path.size()-1]!='/') exe_path += "/"; if ( getenv ( "SUPERTUXKART_DATADIR" ) != NULL ) @@ -160,19 +163,19 @@ FileManager::FileManager() #ifdef __APPLE__ else if( macSetBundlePathIfRelevant( root_dir ) ) { root_dir = root_dir + "data/"; } #endif - else if(m_file_system->existFile("data/stk_config.xml")) + else if(fileExists("data/", version)) root_dir = "data/" ; - else if(m_file_system->existFile("../data/stk_config.xml")) + else if(fileExists("../data/", version)) root_dir = "../data/" ; - else if(m_file_system->existFile("../../data/stk_config.xml")) + else if(fileExists("../../data/", version)) root_dir = "../../data/" ; // Test for old style build environment, with executable in root of stk - else if(m_file_system->existFile(exe_path+"data/stk_config.xml")) + else if(fileExists(exe_path+"data/"+version)) root_dir = (exe_path+"data/").c_str(); // Check for windows cmake style: bld/Debug/bin/supertuxkart.exe - else if (m_file_system->existFile(exe_path + "../../../data/stk_config.xml")) - root_dir = (exe_path + "../../../data/").c_str(); - else if (m_file_system->existFile(exe_path + "../data/stk_config.xml")) + else if (fileExists(exe_path + "../../../data/"+version)) + root_dir = exe_path + "../../../data/"; + else if (fileExists(exe_path + "../data/"+version)) { root_dir = exe_path.c_str(); root_dir += "../data/"; @@ -186,10 +189,10 @@ FileManager::FileManager() #endif } - if (!m_file_system->existFile((root_dir + "stk_config.xml").c_str())) + if (!m_file_system->existFile((root_dir + version).c_str())) { - Log::error("FileManager", "Could not file stk_config.xml in any " - "standard location (esp. ../data)."); + Log::error("FileManager", "Could not file '%s'in any " + "standard location (esp. ../data).", version.c_str()); Log::error("FileManager", "Last location checked '%s'.", root_dir.c_str()); Log::fatal("FileManager", diff --git a/src/io/file_manager.hpp b/src/io/file_manager.hpp index 1c0e7a6b6..0231365e0 100644 --- a/src/io/file_manager.hpp +++ b/src/io/file_manager.hpp @@ -134,6 +134,14 @@ public: std::string searchTexture(const std::string& fname) const; std::string getUserConfigFile(const std::string& fname) const; bool fileExists(const std::string& path) const; + // ------------------------------------------------------------------------ + /** Convenience function to save some typing in the + * file manager constructor. */ + bool fileExists(const char *prefix, const std::string& path) const + { + return fileExists(std::string(prefix) + path); + } + // ------------------------------------------------------------------------ void listFiles (std::set<std::string>& result, const std::string& dir, bool make_full_path=false) const; diff --git a/src/main.cpp b/src/main.cpp index 3c6975a2e..9d6e1088c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1078,7 +1078,7 @@ int handleCmdLine() void initUserConfig() { file_manager = new FileManager(); - user_config = new UserConfig(); // needs file_manager + user_config = new UserConfig(); // needs file_manager user_config->loadConfig(); // Some parts of the file manager needs user config (paths for models // depend on artist debug flag). So init the rest of the file manager From 2f902f769d29867ef33e1521f8016b575c373144 Mon Sep 17 00:00:00 2001 From: hiker <henrichsjoerg@gmail.com> Date: Sat, 1 Aug 2015 22:02:00 +1000 Subject: [PATCH 8/8] Fixed minor memory leak. --- src/states_screens/dialogs/addons_loading.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/states_screens/dialogs/addons_loading.cpp b/src/states_screens/dialogs/addons_loading.cpp index 723460fba..3f0f0d8ec 100644 --- a/src/states_screens/dialogs/addons_loading.cpp +++ b/src/states_screens/dialogs/addons_loading.cpp @@ -331,12 +331,15 @@ void AddonsLoading::stopDownload() // (and not uninstalling an installed one): if(m_download_request) { - // In case of a cancel we can't free the memory, since - // network_http will potentially update the request. So in - // order to avoid a memory leak, we let network_http free - // the request. - //m_download_request->setManageMemory(true); + // In case of a cancel we can't free the memory, since the + // request manager thread is potentially working on this request. So + // in order to avoid a memory leak, we let the request manager + // free the data. This is thread safe since freeing the data is done + // when the request manager handles the result queue - and this is + // done by the main thread (i.e. this thread). + m_download_request->setManageMemory(true); m_download_request->cancel(); + m_download_request = NULL; }; } // startDownload