diff --git a/data/gui/online/recovery_info.stkgui b/data/gui/online/recovery_info.stkgui index 07cffd12c..036dba116 100644 --- a/data/gui/online/recovery_info.stkgui +++ b/data/gui/online/recovery_info.stkgui @@ -12,7 +12,7 @@ - + diff --git a/data/gui/online/registration_info.stkgui b/data/gui/online/registration_info.stkgui index 5d8b6d12a..a99f0f47d 100644 --- a/data/gui/online/registration_info.stkgui +++ b/data/gui/online/registration_info.stkgui @@ -2,7 +2,7 @@
-
@@ -12,7 +12,7 @@ - + diff --git a/data/gui/soccer_player_blue.png b/data/gui/soccer_player_blue.png new file mode 100644 index 000000000..1cc2e815a Binary files /dev/null and b/data/gui/soccer_player_blue.png differ diff --git a/data/gui/soccer_player_red.png b/data/gui/soccer_player_red.png new file mode 100644 index 000000000..7c9e93e9f Binary files /dev/null and b/data/gui/soccer_player_red.png differ diff --git a/data/stk_config.xml b/data/stk_config.xml index 546d30252..2746789d0 100644 --- a/data/stk_config.xml +++ b/data/stk_config.xml @@ -147,6 +147,12 @@ + + + potential rescue loop) - int sector = info.getSector()->getCurrentGraphNode(); - kart->setXYZ( QuadGraph::get()->getQuadOfNode(sector).getCenter()); + return info.getTrackSector()->getCurrentGraphNode(); +} // getRescuePositionIndex - btQuaternion heading(btVector3(0.0f, 1.0f, 0.0f), - m_track->getAngle(sector) ); - kart->setRotation(heading); - // A certain epsilon is added here to the Z coordinate, in case - // that the drivelines are somewhat under the track. Otherwise, the - // kart might be placed a little bit under the track, triggering - // a rescue, ... (experimentally found value) - float epsilon = 0.5f * kart->getKartHeight(); - const Vec3 &xyz = QuadGraph::get()->getQuadOfNode(sector).getCenter(); +// ------------------------------------------------------------------------ +btTransform LinearWorld::getRescueTransform(unsigned int index) const +{ + const Vec3 &xyz = QuadGraph::get()->getQuadOfNode(index).getCenter(); btTransform pos; - pos.setOrigin(xyz+btVector3(0, kart->getKartHeight() + epsilon,0)); + pos.setOrigin(xyz); pos.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f), - m_track->getAngle(sector))); - - kart->getBody()->setCenterOfMassTransform(pos); - kart->setXYZ(pos.getOrigin()); - //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)); - // Also correctly set the graphics, otherwise the kart will - // be displayed for one frame at the incorrect position. - kart->updateGraphics(0, Vec3(0,0,0), btQuaternion(0, 0, 0, 1)); - } - else - { - fprintf(stderr, "WARNING: invalid position after rescue for kart %s " - "on track %s.\n", - (kart->getIdent().c_str()), m_track->getIdent().c_str()); - } - -} // moveKartAfterRescue + m_track->getAngle(index))); + return pos; +} // getRescueTransform //----------------------------------------------------------------------------- /** Find the position (rank) of every kart. ATM it uses a stable O(n^2) @@ -849,14 +828,14 @@ void LinearWorld::updateRacePosition() void LinearWorld::checkForWrongDirection(unsigned int i) { if(!m_karts[i]->getController()->isPlayerController()) return; - if(!m_kart_info[i].getSector()->isOnRoad()|| + if(!m_kart_info[i].getTrackSector()->isOnRoad()|| m_karts[i]->getKartAnimation()) return; const AbstractKart *kart=m_karts[i]; // If the kart can go in more than one directions from the current track // don't do any reverse message handling, since it is likely that there // will be one direction in which it isn't going backwards anyway. - int sector = m_kart_info[i].getSector()->getCurrentGraphNode(); + int sector = m_kart_info[i].getTrackSector()->getCurrentGraphNode(); if(QuadGraph::get()->getNumberOfSuccessors(sector)>1) return; diff --git a/src/modes/linear_world.hpp b/src/modes/linear_world.hpp index ececb9e1d..15ed57ed7 100644 --- a/src/modes/linear_world.hpp +++ b/src/modes/linear_world.hpp @@ -79,7 +79,7 @@ private: float m_overall_distance; /** Stores the current graph node and track coordinates etc. */ - TrackSector m_current_sector; + TrackSector m_track_sector; /** Initialises all fields. */ KartInfo() { reset(); } @@ -92,14 +92,14 @@ private: m_time_at_last_lap = 99999.9f; m_estimated_finish = -1.0f; m_overall_distance = 0.0f; - m_current_sector.reset(); + m_track_sector.reset(); } // reset // -------------------------------------------------------------------- /** Returns a pointer to the current node object. */ - TrackSector *getSector() {return &m_current_sector; } + TrackSector *getTrackSector() {return &m_track_sector; } // -------------------------------------------------------------------- /** Returns a pointer to the current node object. */ - const TrackSector *getSector() const {return &m_current_sector; } + const TrackSector *getTrackSector() const {return &m_track_sector; } }; // ------------------------------------------------------------------------ @@ -133,7 +133,10 @@ public: virtual void getKartsDisplayInfo( std::vector *info) OVERRIDE; - virtual void moveKartAfterRescue(AbstractKart* kart) OVERRIDE; + + virtual unsigned int getNumberOfRescuePositions() const OVERRIDE; + virtual unsigned int getRescuePositionIndex(AbstractKart *kart) OVERRIDE; + virtual btTransform getRescueTransform(unsigned int index) const OVERRIDE; virtual void reset() OVERRIDE; virtual void newLap(unsigned int kart_index) OVERRIDE; @@ -151,7 +154,7 @@ public: * \param kart_index Index of the kart. */ bool isOnRoad(unsigned int kart_index) const { - return m_kart_info[kart_index].getSector()->isOnRoad(); + return m_kart_info[kart_index].getTrackSector()->isOnRoad(); } // isOnRoad // ------------------------------------------------------------------------ @@ -168,7 +171,7 @@ public: * \param kart_index World index of the kart. */ TrackSector& getTrackSector(unsigned int kart_index) { - return m_kart_info[kart_index].m_current_sector; + return m_kart_info[kart_index].m_track_sector; } // getTrackSector // ------------------------------------------------------------------------ diff --git a/src/modes/overworld.cpp b/src/modes/overworld.cpp index 35c395d59..65cdf8f10 100644 --- a/src/modes/overworld.cpp +++ b/src/modes/overworld.cpp @@ -34,9 +34,9 @@ #include "tracks/track.hpp" //----------------------------------------------------------------------------- -OverWorld::OverWorld() : LinearWorld() +OverWorld::OverWorld() : WorldWithRank() { - m_return_to_garage = false; + m_return_to_garage = false; m_stop_music_when_dialog_open = false; } // Overworld @@ -115,7 +115,7 @@ void OverWorld::update(float dt) music_manager->getCurrentMusic()->startMusic(); m_karts[0]->startEngineSFX(); } - LinearWorld::update(dt); + WorldWithRank::update(dt); const unsigned int kart_amount = m_karts.size(); // isn't it cool, on the overworld nitro is free! @@ -136,6 +136,15 @@ void OverWorld::update(float dt) } } // update +//----------------------------------------------------------------------------- +/** This function is not used in the overworld race gui. + */ +void OverWorld::getKartsDisplayInfo( + std::vector *info) +{ + assert(false); +} // getKartsDisplayInfo + //----------------------------------------------------------------------------- /** Override the base class method to change behavior. We don't want wrong * direction messages in the overworld since there is no direction there. @@ -191,96 +200,6 @@ void OverWorld::onFirePressed(Controller* who) } // end for } // onFirePressed -//----------------------------------------------------------------------------- - -btTransform OverWorld::getClosestStartPoint(float currentKart_x, - float currentKart_z) -{ - // find closest point to drop kart on - World *world = World::getWorld(); - const int start_spots_amount = - world->getTrack()->getNumberOfStartPositions(); - assert(start_spots_amount > 0); - - - int closest_id = -1; - float closest_distance = 999999999.0f; - - for (int n=0; ngetTrack()->getStartTransform(n); - const Vec3 &v = s.getOrigin(); - - float absDistance = fabs(currentKart_x - v.getX()) + - fabs(currentKart_z - v.getZ()); - - if (absDistance < closest_distance) - { - closest_distance = absDistance; - closest_id = n; - } - } - - assert(closest_id != -1); - return world->getTrack()->getStartTransform(closest_id); -} // getClosestStartPoint - -//----------------------------------------------------------------------------- -/** Moves a kart to its rescue position. - * \param kart The kart that was rescued. - */ -void OverWorld::moveKartAfterRescue(AbstractKart* kart) -{ - moveKartAfterRescue(kart, 0); -} // moveKartAfterRescue(AbstractKart*) - -//----------------------------------------------------------------------------- - -void OverWorld::moveKartAfterRescue(AbstractKart* kart, float angle) -{ - // find closest point to drop kart on - World *world = World::getWorld(); - const int start_spots_amount = - world->getTrack()->getNumberOfStartPositions(); - assert(start_spots_amount > 0); - - const float currentKart_x = kart->getXYZ().getX(); - const float currentKart_z = kart->getXYZ().getZ(); - - const btTransform& s = getClosestStartPoint(currentKart_x, currentKart_z); - 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), 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("overworld", "Invalid position after rescue for kart %s " - "on track %s.", (kart->getIdent().c_str()), - m_track->getIdent().c_str()); - } -} // moveKartAfterRescue - //----------------------------------------------------------------------------- /** Called when a mouse click happens. If the click happened while the mouse * was hovering on top of a challenge, the kart will be teleported to @@ -294,14 +213,19 @@ void OverWorld::onMouseClick(int x, int y) if(challenge) { + // Use the 'get closest start point' rescue function + // from WorldWithRank by setting the kart's position to + // be the location of the challenge bubble. AbstractKart* kart = getKart(0); - const btTransform& s = getClosestStartPoint(challenge->m_position.X, - challenge->m_position.Z); - const Vec3 &xyz = s.getOrigin(); - float angle = atan2(challenge->m_position.X - xyz[0], - challenge->m_position.Z - xyz[2]); - kart->setXYZ(xyz); - moveKartAfterRescue(kart, angle); + kart->setXYZ(challenge->m_position); + + unsigned int index = getRescuePositionIndex(kart); + btTransform s = getRescueTransform(index); + const btVector3 &xyz = s.getOrigin(); + float angle = atan2(challenge->m_position.X - xyz[0], + challenge->m_position.Z - xyz[2]); + s.setRotation( btQuaternion(btVector3(0.0f, 1.0f, 0.0f), angle) ); + moveKartTo(kart, s); return; } } // onMouseClick diff --git a/src/modes/overworld.hpp b/src/modes/overworld.hpp index 8c54f0350..a1dbdb752 100644 --- a/src/modes/overworld.hpp +++ b/src/modes/overworld.hpp @@ -20,7 +20,7 @@ #include -#include "modes/linear_world.hpp" +#include "modes/world_with_rank.hpp" #include "utils/aligned_array.hpp" #include "LinearMath/btTransform.h" @@ -32,7 +32,7 @@ * linear. * \ingroup modes */ -class OverWorld : public LinearWorld +class OverWorld : public WorldWithRank { protected: @@ -41,10 +41,6 @@ protected: bool m_return_to_garage; - void moveKartAfterRescue(AbstractKart* kart, float angle); - - btTransform getClosestStartPoint(float currentKart_x, float currentKart_z); - public: OverWorld(); virtual ~OverWorld(); @@ -52,7 +48,8 @@ public: static void enterOverWorld(); virtual void update(float delta) OVERRIDE; - + virtual void getKartsDisplayInfo( + std::vector *info) OVERRIDE; // ------------------------------------------------------------------------ /** Returns if this race mode has laps. */ virtual bool raceHasLaps() OVERRIDE { return false; } @@ -77,8 +74,6 @@ public: // ------------------------------------------------------------------------ void scheduleSelectKart() { m_return_to_garage = true; } // ------------------------------------------------------------------------ - virtual void moveKartAfterRescue(AbstractKart* kart) OVERRIDE; - // ------------------------------------------------------------------------ virtual void onMouseClick(int x, int y) OVERRIDE; }; diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 22e4170f9..0d05351e6 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -191,88 +191,7 @@ 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; ngetTrack()->getStartTransform(n); - const Vec3 &v=s.getOrigin(); - float accumulatedDistance = .0f; - bool spawnPointClear = true; - - for(unsigned int k=0; kgetKart(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 = world->getTrack()->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 - { - fprintf(stderr, "WARNING: invalid position after rescue for kart %s on track %s.\n", - (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 06aa1bcf1..591c0659a 100644 --- a/src/modes/soccer_world.hpp +++ b/src/modes/soccer_world.hpp @@ -64,7 +64,6 @@ public: virtual void getKartsDisplayInfo( std::vector *info); virtual bool raceHasLaps(){ return false; } - virtual void moveKartAfterRescue(AbstractKart* kart); virtual const std::string& getIdent() const; diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp index 0da54b42b..023bb4c3f 100644 --- a/src/modes/three_strikes_battle.cpp +++ b/src/modes/three_strikes_battle.cpp @@ -1,3 +1,5 @@ + + // SuperTuxKart - a fun racing game with go-kart // Copyright (C) 2006 SuperTuxKart-Team // @@ -477,83 +479,52 @@ void ThreeStrikesBattle::getKartsDisplayInfo( } // getKartsDisplayInfo //----------------------------------------------------------------------------- -/** Moves a kart to its rescue position. - * \param kart The kart that was rescued. +/** 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. */ -void ThreeStrikesBattle::moveKartAfterRescue(AbstractKart* kart) + +unsigned int ThreeStrikesBattle::getRescuePositionIndex(AbstractKart *kart) { - // find closest point to drop kart on - World *world = World::getWorld(); - const int start_spots_amount = world->getTrack()->getNumberOfStartPositions(); + const int start_spots_amount = 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(); + int furthest_id_found = -1; for(int n=0; ngetTrack()->getStartTransform(n); + const btTransform &s = getTrack()->getStartTransform(n); const Vec3 &v=s.getOrigin(); - float accumulatedDistance = .0f; - bool spawnPointClear = true; + float accumulated_distance = .0f; + bool spawn_point_clear = true; for(unsigned int k=0; kgetKart(k); - const float currentKart_x = currentKart->getXYZ().getX(); - const float currentKartk_z = currentKart->getXYZ().getZ(); - - if(kart_x!=currentKart_x && kart_z !=currentKartk_z) + 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) { - float absDistance = fabs(currentKart_x - v.getX()) + - fabs(currentKartk_z - v.getZ()); - if(absDistance < CLEAR_SPAWN_RANGE) - { - spawnPointClear = false; - break; - } - accumulatedDistance += absDistance; + spawn_point_clear = false; + break; } + accumulated_distance += sqrt(abs_distance2); } - if(largest_accumulated_distance_found < accumulatedDistance && spawnPointClear) + if(accumulated_distance > largest_accumulated_distance_found && + spawn_point_clear) { furthest_id_found = n; - largest_accumulated_distance_found = accumulatedDistance; + largest_accumulated_distance_found = accumulated_distance; } } assert(furthest_id_found != -1); - const btTransform &s = world->getTrack()->getStartTransform(furthest_id_found); - const Vec3 &xyz = s.getOrigin(); - kart->setXYZ(xyz); - kart->setRotation(s.getRotation()); + return furthest_id_found; +} // getRescuePositionIndex - //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 - { - fprintf(stderr, "WARNING: invalid position after rescue for kart %s on track %s.\n", - (kart->getIdent().c_str()), m_track->getIdent().c_str()); - } -} // moveKartAfterRescue diff --git a/src/modes/three_strikes_battle.hpp b/src/modes/three_strikes_battle.hpp index 276dcc468..7cb8c8eb3 100644 --- a/src/modes/three_strikes_battle.hpp +++ b/src/modes/three_strikes_battle.hpp @@ -16,8 +16,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef THREE_STRIKES_HPP -#define THREE_STRIKES_HPP +#ifndef THREE_STRIKES_BATTLE_HPP +#define THREE_STRIKES_BATTLE_HPP #include "modes/world_with_rank.hpp" @@ -28,8 +28,6 @@ #include -#define CLEAR_SPAWN_RANGE 5 - class PhysicalObject; /** @@ -99,7 +97,7 @@ public: virtual void getKartsDisplayInfo( std::vector *info); virtual bool raceHasLaps(){ return false; } - virtual void moveKartAfterRescue(AbstractKart* kart); + virtual unsigned int getRescuePositionIndex(AbstractKart *kart); virtual const std::string& getIdent() const; diff --git a/src/modes/tutorial_world.cpp b/src/modes/tutorial_world.cpp index 2f89f247a..70ddabad8 100644 --- a/src/modes/tutorial_world.cpp +++ b/src/modes/tutorial_world.cpp @@ -7,88 +7,4 @@ TutorialWorld::TutorialWorld() { m_stop_music_when_dialog_open = false; -} - -// ----------------------------------------------------------------------------- - -void TutorialWorld::moveKartAfterRescue(AbstractKart* kart) -{ - float angle = 0; - - // find closest point to drop kart on - World *world = World::getWorld(); - const int start_spots_amount = - world->getTrack()->getNumberOfStartPositions(); - assert(start_spots_amount > 0); - - const float currentKart_x = kart->getXYZ().getX(); - const float currentKart_z = kart->getXYZ().getZ(); - - const btTransform& s = getClosestStartPoint(currentKart_x, currentKart_z); - 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), 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 - { - fprintf(stderr, "WARNING: invalid position after rescue for kart %s" - "on track %s.\n", - (kart->getIdent().c_str()), m_track->getIdent().c_str()); - } - -} // moveKartAfterRescue - -// ----------------------------------------------------------------------------- - -btTransform TutorialWorld::getClosestStartPoint(float currentKart_x, - float currentKart_z) -{ - // find closest point to drop kart on - World *world = World::getWorld(); - const int start_spots_amount = - world->getTrack()->getNumberOfStartPositions(); - assert(start_spots_amount > 0); - - - int closest_id = -1; - float closest_distance = 999999999.0f; - - for (int n=0; ngetTrack()->getStartTransform(n); - const Vec3 &v = s.getOrigin(); - - float absDistance = fabs(currentKart_x - v.getX()) + - fabs(currentKart_z - v.getZ()); - - if (absDistance < closest_distance) - { - closest_distance = absDistance; - closest_id = n; - } - } - - assert(closest_id != -1); - return world->getTrack()->getStartTransform(closest_id); -} // getClosestStartPoint +} // TutorialWorld \ No newline at end of file diff --git a/src/modes/tutorial_world.hpp b/src/modes/tutorial_world.hpp index 35be6fea9..5c2b3b2a1 100644 --- a/src/modes/tutorial_world.hpp +++ b/src/modes/tutorial_world.hpp @@ -6,13 +6,32 @@ class TutorialWorld : public StandardRace { -private: - btTransform getClosestStartPoint(float currentKart_x, float currentKart_z); public: TutorialWorld(); + virtual unsigned int getNumberOfRescuePositions() const OVERRIDE + { + // Don't use LinearWorld's function, but WorldWithRank, since the + // latter is based on rescuing to start positions + return WorldWithRank::getNumberOfRescuePositions(); + } + // ------------------------------------------------------------------------ + /** Determines the rescue position index of the specified kart. */ + virtual unsigned int getRescuePositionIndex(AbstractKart *kart) OVERRIDE + { + // Don't use LinearWorld's function, but WorldWithRank, since the + // latter is based on rescuing to start positions + return WorldWithRank::getRescuePositionIndex(kart); + } + // ------------------------------------------------------------------------ + /** Returns the bullet transformation for the specified rescue index. */ + virtual btTransform getRescueTransform(unsigned int index) const OVERRIDE + { + // Don't use LinearWorld's function, but WorldWithRank, since the + // latter is based on rescuing to start positions + return WorldWithRank::getRescueTransform(index); + } - virtual void moveKartAfterRescue(AbstractKart* kart) OVERRIDE; -}; +}; // class TutorialWorld #endif diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 427a27caf..92e76e05f 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -79,7 +79,22 @@ World* World::m_world = NULL; * of all karts is set (i.e. in a normal race the arrival time for karts * will be estimated), highscore is updated, and the race result gui * is being displayed. + * Rescuing is handled via the three functions: + * getNumberOfRescuePositions() - which returns the number of rescue + * positions defined. + * getRescuePositionIndex(AbstractKart *kart) - which determines the + * index of the rescue position to be used for the given kart. + * getRescueTransform(unsigned int index) - which returns the transform + * (i.e. position and rotation) for the specified rescue + * position. + * This allows the world class to do some tests to make sure all rescue + * positions are valid (when started with --track-debug). It tries to + * place all karts on all rescue positions. If there are any problems + * (e.g. a rescue position not over terrain (perhaps because it is too + * low); or the rescue position is on a texture which will immediately + * trigger another rescue), a warning message will be printed. */ + //----------------------------------------------------------------------------- /** Constructor. Note that in the constructor it is not possible to call any * functions that use World::getWorld(), since this is only defined @@ -320,7 +335,7 @@ Controller* World::loadAIController(AbstractKart *kart) controller = new SkiddingAI(kart); break; default: - fprintf(stderr, "Warning: Unknown robot, using default.\n"); + Log::warn("World", "Unknown AI, using default."); controller = new SkiddingAI(kart); break; } @@ -471,65 +486,31 @@ void World::resetAllKarts() // If track checking is requested, check all rescue positions if // they are heigh enough. - if(race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES && - UserConfigParams::m_track_debug) + if(UserConfigParams::m_track_debug) { - Vec3 eps = Vec3(0,1.5f*m_karts[0]->getKartHeight(),0); - for(unsigned int quad=0; quadgetNumNodes(); quad++) - { - const Quad &q = QuadGraph::get()->getQuadOfNode(quad); - const Vec3 center = q.getCenter(); - // We have to test for all karts, since the karts have different - // heights and so things might change from kart to kart. - for(unsigned int kart_id=0; kart_idsetXYZ(center); - - btQuaternion heading(btVector3(0.0f, 1.0f, 0.0f), - m_track->getAngle(quad) ); - kart->setRotation(heading); - - btTransform pos; - pos.setOrigin(center+eps); - pos.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f), - m_track->getAngle(quad)) ); - kart->getBody()->setCenterOfMassTransform(pos); - - bool kart_over_ground = m_track->findGround(kart); - if(kart_over_ground) - { - const Vec3 &xyz = kart->getTrans().getOrigin() - + Vec3(0,0.3f,0); - if(dynamic_cast(kart)) - dynamic_cast(kart)->getTerrainInfo() - ->update(xyz); - const Material *material = kart->getMaterial(); - if(!material || material->isDriveReset()) - kart_over_ground = false; - } - if(!kart_over_ground) - { - printf("Kart '%s' not over quad '%d'\n", - kart->getIdent().c_str(), quad); - printf("Center point: %f %f %f\n", - center.getX(), center.getY(), center.getZ()); - - } - } // for kart_idreset(); - } + } // for kart_idgetIdent().c_str()); + Log::error("World", + "No valid starting position for kart %d on track %s.", + (int)(i-m_karts.begin()), m_track->getIdent().c_str()); if (UserConfigParams::m_artist_debug_mode) { - fprintf(stderr, "Activating fly mode.\n"); + Log::warn("World", "Activating fly mode."); (*i)->flyUp(); continue; } @@ -598,14 +578,14 @@ void World::resetAllKarts() &normal); if(!material) { - fprintf(stderr, - "ERROR: no valid starting position for " - "kart %d on track %s.\n", - (int)(i-m_karts.begin()), - m_track->getIdent().c_str()); + Log::error("World", + "No valid starting position for kart %d " + "on track %s.", + (int)(i-m_karts.begin()), + m_track->getIdent().c_str()); if (UserConfigParams::m_artist_debug_mode) { - fprintf(stderr, "Activating fly mode.\n"); + Log::warn("World", "Activating fly mode."); (*i)->flyUp(); continue; } @@ -637,6 +617,44 @@ void World::resetAllKarts() } } // resetAllKarts +// ---------------------------------------------------------------------------- +/** Places a kart that is rescued. It calls getRescuePositionIndex to find + * to which rescue position the kart should be moved, then getRescueTransform + * to get the position and rotation of this rescue position, and then moves + * the kart. + * \param kart The kart that is rescued. + */ +void World::moveKartAfterRescue(AbstractKart* kart) +{ + unsigned int index = getRescuePositionIndex(kart); + btTransform t = getRescueTransform(index); + moveKartTo(kart, t); +} // moveKartAfterRescue + +// ---------------------------------------------------------------------------- +/** Places the kart at a given position and rotation. + * \param kart The kart to be moved. + * \param transform + */ +void World::moveKartTo(AbstractKart* kart, const btTransform &transform) +{ + btTransform pos(transform); + + // Move the kart + Vec3 xyz = pos.getOrigin() + btVector3(0, 0.5f*kart->getKartHeight(),0.0f); + + pos.setOrigin(xyz); + kart->setXYZ(xyz); + kart->setRotation(pos.getRotation()); + + kart->getBody()->setCenterOfMassTransform(pos); + + // Project kart to surface of track + // This will set the physics transform + m_track->findGround(kart); + +} // moveKartTo + // ---------------------------------------------------------------------------- void World::schedulePause(Phase phase) { @@ -730,13 +748,15 @@ void World::updateWorld(float dt) InputDevice* device = input_manager->getDeviceList()->getKeyboard(0); // Create player and associate player with keyboard - StateManager::get()->createActivePlayer(unlock_manager->getCurrentPlayer(), - device); + StateManager::get() + ->createActivePlayer(unlock_manager->getCurrentPlayer(), + device); - if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL) + if (!kart_properties_manager->getKart(UserConfigParams::m_default_kart)) { - fprintf(stderr, "[MainMenuScreen] WARNING: cannot find kart '%s', will revert to default\n", - UserConfigParams::m_default_kart.c_str()); + Log::warn("World", + "Cannot find kart '%s', will revert to default.", + UserConfigParams::m_default_kart.c_str()); UserConfigParams::m_default_kart.revertToDefaults(); } race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart); @@ -912,11 +932,11 @@ void World::updateHighscores(int* best_highscore_rank, int* best_finish_time, // the kart location data is wrong #ifdef DEBUG - fprintf(stderr, "Error, incorrect kart positions:\n"); + Log::error("World", "Incorrect kart positions:"); for (unsigned int i=0; igetPosition()); + Log::error("World", "i=%d position %d.",i, + m_karts[i]->getPosition()); } #endif continue; diff --git a/src/modes/world.hpp b/src/modes/world.hpp index 838723669..c981c960c 100644 --- a/src/modes/world.hpp +++ b/src/modes/world.hpp @@ -33,6 +33,8 @@ #include "states_screens/state_manager.hpp" #include "utils/random_generator.hpp" +#include "LinearMath/btTransform.h" + class AbstractKart; class btRigidBody; class Controller; @@ -156,6 +158,7 @@ protected: virtual void update(float dt); virtual void createRaceGUI(); void updateTrack(float dt); + void moveKartTo(AbstractKart* kart, const btTransform &t); // ------------------------------------------------------------------------ /** Used for AI karts that are still racing when all player kart finished. * Generally it should estimate the arrival time for those karts, but as @@ -192,13 +195,19 @@ public: /** Each game mode should have a unique identifier. Override * this method in child classes to provide it. */ - virtual const std::string& - getIdent() const = 0; + virtual const std::string& getIdent() const = 0; // ------------------------------------------------------------------------ - /** Since each mode will have a different way of deciding where a rescued - * kart is dropped, this method will be called and each mode can implement - * it. */ - virtual void moveKartAfterRescue(AbstractKart* kart) = 0; + /** Returns the number of rescue positions on a given track and game + * mode. */ + virtual unsigned int getNumberOfRescuePositions() const OVERRIDE = 0; + // ------------------------------------------------------------------------ + /** Determines the rescue position index of the specified kart. */ + virtual unsigned int getRescuePositionIndex(AbstractKart *kart) = 0; + // ------------------------------------------------------------------------ + /** Returns the bullet transformation for the specified rescue index. */ + virtual btTransform getRescueTransform(unsigned int index) const = 0; + // ------------------------------------------------------------------------ + void moveKartAfterRescue(AbstractKart* kart); // ------------------------------------------------------------------------ /** Called when it is needed to know whether this kind of race involves * counting laps. */ diff --git a/src/modes/world_with_rank.cpp b/src/modes/world_with_rank.cpp index 47f0aee95..e4668ef41 100644 --- a/src/modes/world_with_rank.cpp +++ b/src/modes/world_with_rank.cpp @@ -18,7 +18,9 @@ #include "modes/world_with_rank.hpp" #include "karts/abstract_kart.hpp" +#include "karts/kart_properties.hpp" #include "race/history.hpp" +#include "tracks/track.hpp" #include @@ -120,3 +122,53 @@ void WorldWithRank::endSetKartPositions() } // endSetKartPositions +//----------------------------------------------------------------------------- +/** WorldWithRank uses the start position as rescue positions. So return + * the number of start positions. + */ +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. + */ +unsigned int WorldWithRank::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; ngetStartTransform(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 + +// ---------------------------------------------------------------------------- +/** Returns the start transform with the give index. + * \param rescue_pos Index of the start position to be returned. + * \returns The transform of the corresponding start position. + */ +btTransform WorldWithRank::getRescueTransform(unsigned int rescue_pos) const +{ + return getTrack()->getStartTransform(rescue_pos); +} // getRescueTransform + diff --git a/src/modes/world_with_rank.hpp b/src/modes/world_with_rank.hpp index a0995c89c..6f3207bd9 100644 --- a/src/modes/world_with_rank.hpp +++ b/src/modes/world_with_rank.hpp @@ -28,7 +28,10 @@ class AbstractKart; * 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 setKartPosition(kart id, position) - * and this class is used to access the ranks from other objects. + * and this class is used to access the ranks from other objects. This class + * adds a convenient rescue implementation: a kart is rescued to the closest + * start point. This is useful for battle, soccer, ... modes. Linear world + * defines its own rescue functions and will overwrite this. * \ingroup modes */ class WorldWithRank : public World @@ -51,6 +54,8 @@ protected: bool m_position_setting_initialised; #endif + unsigned int getClosestStartPoint(AbstractKart *kart); + public: WorldWithRank() : World() {} /** call just after instanciating. can't be moved to the contructor as child @@ -64,8 +69,13 @@ public: bool setKartPosition(unsigned int kart_id, unsigned int position); void endSetKartPositions(); - AbstractKart* getKartAtPosition(unsigned int p) const; + + virtual unsigned int getNumberOfRescuePositions() const OVERRIDE; + virtual unsigned int getRescuePositionIndex(AbstractKart *kart) OVERRIDE; + virtual btTransform getRescueTransform(unsigned int index) const OVERRIDE; + + }; // WorldWithRank #endif diff --git a/src/states_screens/addons_screen.cpp b/src/states_screens/addons_screen.cpp index 9df3e15d8..a4a9ccc82 100644 --- a/src/states_screens/addons_screen.cpp +++ b/src/states_screens/addons_screen.cpp @@ -214,7 +214,7 @@ void AddonsScreen::loadList() // Get the filter by rating. GUIEngine::SpinnerWidget* w_filter_rating = getWidget("filter_rating"); - float rating = 1.0 + w_filter_rating->getValue() / 2.0; + float rating = 1.0f + w_filter_rating->getValue() / 2.0f; // First create a list of sorted entries PtrVector sorted_list; diff --git a/src/states_screens/dialogs/tutorial_message_dialog.cpp b/src/states_screens/dialogs/tutorial_message_dialog.cpp index 5cb01ca23..91cb26c35 100644 --- a/src/states_screens/dialogs/tutorial_message_dialog.cpp +++ b/src/states_screens/dialogs/tutorial_message_dialog.cpp @@ -21,6 +21,7 @@ #include "guiengine/screen.hpp" #include "guiengine/widgets/button_widget.hpp" #include "guiengine/widgets/label_widget.hpp" +#include "karts/abstract_kart.hpp" #include "modes/world.hpp" #include "states_screens/state_manager.hpp" #include "utils/translation.hpp" @@ -48,6 +49,8 @@ TutorialMessageDialog::TutorialMessageDialog(irr::core::stringw msg, bool stopGa ButtonWidget* cancelbtn = getWidget("continue"); cancelbtn->setFocusForPlayer(PLAYER_ID_GAME_MASTER); + + World::getWorld()->getKart(0)->getControls().reset(); } // ------------------------------------------------------------------------------------------------------ diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index a46863458..d3cc53344 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -526,7 +526,7 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart, video::SMaterial m; - if(kart->getControls().m_nitro) + if(kart->getControls().m_nitro || kart->isOnMinNitroTime()) m.setTexture(0, m_gauge_full_bright); else m.setTexture(0, m_gauge_full); diff --git a/src/states_screens/race_setup_screen.cpp b/src/states_screens/race_setup_screen.cpp index b143cfbfd..ef9509c60 100644 --- a/src/states_screens/race_setup_screen.cpp +++ b/src/states_screens/race_setup_screen.cpp @@ -77,44 +77,12 @@ void RaceSetupScreen::eventCallback(Widget* widget, const std::string& name, con { if (name == "difficulty") { - RibbonWidget* w = dynamic_cast(widget); - assert(w != NULL); - const std::string& selection = w->getSelectionIDString(PLAYER_ID_GAME_MASTER); - - if (selection == "novice") - { - UserConfigParams::m_difficulty = RaceManager::DIFFICULTY_EASY; - race_manager->setDifficulty(RaceManager::DIFFICULTY_EASY); - } - else if (selection == "intermediate") - { - UserConfigParams::m_difficulty = RaceManager::DIFFICULTY_MEDIUM; - race_manager->setDifficulty(RaceManager::DIFFICULTY_MEDIUM); - } - else if (selection == "expert") - { - UserConfigParams::m_difficulty = RaceManager::DIFFICULTY_HARD; - race_manager->setDifficulty(RaceManager::DIFFICULTY_HARD); - } - else if (selection == "best") - { - if (unlock_manager->getCurrentSlot()->isLocked("difficulty_best")) - { - unlock_manager->playLockSound(); - UserConfigParams::m_difficulty = RaceManager::DIFFICULTY_HARD; - race_manager->setDifficulty(RaceManager::DIFFICULTY_HARD); - w->setSelection(2, PLAYER_ID_GAME_MASTER); - w->setFocusForPlayer(PLAYER_ID_GAME_MASTER); - } - else - { - UserConfigParams::m_difficulty = RaceManager::DIFFICULTY_BEST; - race_manager->setDifficulty(RaceManager::DIFFICULTY_BEST); - } - } + assignDifficulty(); } else if (name == "gamemode") { + assignDifficulty(); + DynamicRibbonWidget* w = dynamic_cast(widget); const std::string& selectedMode = w->getSelectionIDString(PLAYER_ID_GAME_MASTER); @@ -185,6 +153,47 @@ void RaceSetupScreen::eventCallback(Widget* widget, const std::string& name, con // ----------------------------------------------------------------------------- +void RaceSetupScreen::assignDifficulty() +{ + RibbonWidget* difficulty = getWidget("difficulty"); + assert(difficulty != NULL); + const std::string& difficultySelection = difficulty->getSelectionIDString(PLAYER_ID_GAME_MASTER); + + if (difficultySelection == "novice") + { + UserConfigParams::m_difficulty = RaceManager::DIFFICULTY_EASY; + race_manager->setDifficulty(RaceManager::DIFFICULTY_EASY); + } + else if (difficultySelection == "intermediate") + { + UserConfigParams::m_difficulty = RaceManager::DIFFICULTY_MEDIUM; + race_manager->setDifficulty(RaceManager::DIFFICULTY_MEDIUM); + } + else if (difficultySelection == "expert") + { + UserConfigParams::m_difficulty = RaceManager::DIFFICULTY_HARD; + race_manager->setDifficulty(RaceManager::DIFFICULTY_HARD); + } + else if (difficultySelection == "best") + { + if (unlock_manager->getCurrentSlot()->isLocked("difficulty_best")) + { + unlock_manager->playLockSound(); + UserConfigParams::m_difficulty = RaceManager::DIFFICULTY_HARD; + race_manager->setDifficulty(RaceManager::DIFFICULTY_HARD); + difficulty->setSelection(2, PLAYER_ID_GAME_MASTER); + difficulty->setFocusForPlayer(PLAYER_ID_GAME_MASTER); + } + else + { + UserConfigParams::m_difficulty = RaceManager::DIFFICULTY_BEST; + race_manager->setDifficulty(RaceManager::DIFFICULTY_BEST); + } + } +} + +// ----------------------------------------------------------------------------- + void RaceSetupScreen::onGameModeChanged() { DynamicRibbonWidget* w2 = getWidget("gamemode"); diff --git a/src/states_screens/race_setup_screen.hpp b/src/states_screens/race_setup_screen.hpp index 4fe3d759a..4b35e428e 100644 --- a/src/states_screens/race_setup_screen.hpp +++ b/src/states_screens/race_setup_screen.hpp @@ -39,6 +39,8 @@ class RaceSetupScreen : public GUIEngine::Screen, public GUIEngine::ScreenSingle void onGameModeChanged(); + void assignDifficulty(); + public: /** \brief implement callback from parent class GUIEngine::Screen */ diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index ae56a65d4..c16d41fcd 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -121,6 +121,7 @@ Track::Track(const std::string &filename) m_minimap_x_scale = 1.0f; m_minimap_y_scale = 1.0f; m_all_nodes.clear(); + m_all_physics_only_nodes.clear(); m_all_cached_meshes.clear(); loadTrackInfo(); } // Track @@ -182,6 +183,7 @@ void Track::cleanup() irr_driver->removeNode(m_all_nodes[i]); } m_all_nodes.clear(); + m_all_physics_only_nodes.clear(); m_all_emitters.clearAndDeleteAll(); @@ -955,6 +957,8 @@ bool Track::loadMainTrack(const XMLNode &root) model_name=""; n->get("model", &model_name); full_path = m_root+model_name; + std::string interaction; + n->get("interaction", &interaction); // a special challenge orb object for overworld std::string challenge; @@ -1035,7 +1039,6 @@ bool Track::loadMainTrack(const XMLNode &root) scene_node->setPosition(xyz); scene_node->setRotation(hpr); scene_node->setScale(scale); - #ifdef DEBUG std::string debug_name = model_name+" (static track-object)"; scene_node->setName(debug_name.c_str()); @@ -1117,7 +1120,10 @@ bool Track::loadMainTrack(const XMLNode &root) } else { - m_all_nodes.push_back( scene_node ); + if(interaction=="physics-only") + m_all_physics_only_nodes.push_back( scene_node ); + else + m_all_nodes.push_back( scene_node ); } } @@ -1138,6 +1144,16 @@ bool Track::loadMainTrack(const XMLNode &root) { convertTrackToBullet(m_all_nodes[i]); } + + // Now convert all objects that are only used for the physics + // (like invisible walls). + for(unsigned int i=0; iremoveNode(m_all_physics_only_nodes[i]); + } + m_all_physics_only_nodes.clear(); + if (m_track_mesh == NULL) { Log::fatal("track", "m_track_mesh == NULL, cannot loadMainTrack\n"); @@ -2068,17 +2084,17 @@ bool Track::findGround(AbstractKart *kart) } - btTransform t = kart->getBody()->getCenterOfMassTransform(); - // The computer offset is slightly too large, it should take - // the default suspension rest insteat of suspension rest (i.e. the - // length of the suspension with the weight of the kart resting on - // it). On the other hand this initial bouncing looks nice imho - // - so I'll leave it in for now. - float offset = kart->getKartProperties()->getSuspensionRest() + - kart->getKartProperties()->getWheelRadius(); - t.setOrigin(hit_point+Vec3(0, offset, 0) ); - kart->getBody()->setCenterOfMassTransform(t); - kart->setTrans(t); + btTransform t = kart->getBody()->getCenterOfMassTransform(); + // The computer offset is slightly too large, it should take + // the default suspension rest insteat of suspension rest (i.e. the + // length of the suspension with the weight of the kart resting on + // it). On the other hand this initial bouncing looks nice imho + // - so I'll leave it in for now. + float offset = kart->getKartProperties()->getSuspensionRest() + + kart->getKartProperties()->getWheelRadius(); + t.setOrigin(hit_point+Vec3(0, offset, 0) ); + kart->getBody()->setCenterOfMassTransform(t); + kart->setTrans(t); return true; } // findGround diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 1fb7caa89..0d180f3ef 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -174,8 +174,14 @@ private: /** The base dir of all files of this track. */ std::string m_root; std::vector m_groups; + + /** The list of all nodes. */ std::vector m_all_nodes; + /** The list of all nodes that are to be converted into physics, + * but not to be drawn (e.g. invisible walls). */ + std::vector m_all_physics_only_nodes; + /** The list of all meshes that are loaded from disk, which means * that those meshes are being cached by irrlicht, and need to be freed. */ std::vector m_all_cached_meshes; diff --git a/src/tracks/track_object.hpp b/src/tracks/track_object.hpp index 23380c592..e53cf53de 100644 --- a/src/tracks/track_object.hpp +++ b/src/tracks/track_object.hpp @@ -90,7 +90,7 @@ public: TrackObjectPresentation* presentation, bool is_dynamic, const PhysicalObject::Settings* physicsSettings); - ~TrackObject(); + virtual ~TrackObject(); virtual void update(float dt); virtual void reset(); /** To finish object constructions. Called after the track model diff --git a/src/utils/log.hpp b/src/utils/log.hpp index 4552196bb..46627cec2 100644 --- a/src/utils/log.hpp +++ b/src/utils/log.hpp @@ -20,6 +20,7 @@ #ifndef HEADER_LOG_HPP #define HEADER_LOG_HPP +#include #include #include #include @@ -66,7 +67,9 @@ public: static void printMessage(int level, const char *component, const char *format, VALIST va_list); // ------------------------------------------------------------------------ - /** A simple macro to define the various log functions. */ + /** A simple macro to define the various log functions. + * Note that an assert is added so that a debugger is triggered + * when debugging. */ #define LOG(NAME, LEVEL) \ static void NAME(const char *component, const char *format, ...) \ { \ @@ -76,7 +79,11 @@ public: printMessage(LEVEL, component, format, args); \ va_end(args); \ \ - if (LEVEL == LL_FATAL) exit(1); \ + if (LEVEL == LL_FATAL) \ + { \ + assert(false); \ + exit(1); \ + } \ } LOG(verbose, LL_VERBOSE); LOG(debug, LL_DEBUG); diff --git a/src/utils/string_utils.cpp b/src/utils/string_utils.cpp index fbf460909..20fb31a68 100644 --- a/src/utils/string_utils.cpp +++ b/src/utils/string_utils.cpp @@ -19,9 +19,11 @@ #include "utils/string_utils.hpp" +#include "utils/log.hpp" + #include "coreutil.h" -#include "math.h" +#include #include #include #include @@ -191,14 +193,14 @@ namespace StringUtils } catch (std::exception& e) { - fprintf(stderr, - "Fatal error in split(std::string) : %s @ line %i : %s\n", + Log::error("StringUtils", + "Error in split(std::string) : %s @ line %i : %s.", __FILE__, __LINE__, e.what()); - printf("Splitting %s\n", s.c_str()); + Log::error("StringUtils", "Splitting '%s'.", s.c_str()); for (int n=0; n<(int)result.size(); n++) { - printf("Split : %s\n", result[n].c_str()); + Log::error("StringUtils", "Split : %s", result[n].c_str()); } assert(false); // in debug mode, trigger debugger @@ -253,10 +255,9 @@ namespace StringUtils catch (std::exception& e) { (void)e; // avoid warning about unused variable - fprintf(stderr, - "Fatal error in split(stringw) : %s @ line %i : %s\n", - __FILE__, __LINE__, e.what()); - assert(false); // in dbug mode, trigger debugger + Log::fatal("StringUtils", + "Fatal error in split(stringw) : %s @ line %i : '%s'.", + __FILE__, __LINE__, e.what()); exit(1); } } // split @@ -310,8 +311,9 @@ namespace StringUtils catch (std::exception& e) { (void)e; // avoid warning about unused variable - fprintf(stderr, "Fatal error in splitPath : %s @ line %i\n", - __FILE__, __LINE__); + Log::fatal("StringUtils", + "Fatal error in splitPath : %s @ line %i: '%s'.", + __FILE__, __LINE__, path.c_str()); exit(1); } } // splitPath @@ -340,10 +342,10 @@ namespace StringUtils { if (insertValID >= all_vals.size()) { - fprintf(stderr, - "[StringUtils::insertValues] ERROR: " - "Invalid number of arguments in '%s'\n", - s.c_str()); + Log::warn("StringUtils", + "insertValues: " + "Invalid number of arguments in '%s'.", + s.c_str()); new_string += "??" + sv[i].substr(2); } else @@ -358,9 +360,9 @@ namespace StringUtils const unsigned int index = sv[i][1] - '0'; if (index >= all_vals.size()) { - fprintf(stderr,"[StringUtils::insertValues] ERROR:" - " Invalid argument index in '%s' " - "for %i\n", s.c_str(), index); + Log::warn("StringUtils", "insertValues: " + " Invalid argument index in '%s' " + "for %i.", s.c_str(), index); new_string += "??" + sv[i].substr(2); } else @@ -379,8 +381,9 @@ namespace StringUtils catch (std::exception& e) { (void)e; // avoid warning about unused variable - fprintf(stderr, "Fatal error in insertValues(std::string) : %s @ " - "line %i\n", __FILE__, __LINE__); + Log::fatal("StringUtils", + "Fatal error in insertValues(std::string) : %s @ " + "line %i: '%s'", __FILE__, __LINE__, s.c_str()); exit(1); } } @@ -411,10 +414,9 @@ namespace StringUtils { if (insertValID >= all_vals.size()) { - fprintf(stderr, - "[StringUtils::insertValues] ERROR: " - "Invalid number of arguments in '%s'\n", - irr::core::stringc(s.c_str()).c_str()); + Log::warn("StringUtils", "insertValues: " + "Invalid number of arguments in '%s'\n", + irr::core::stringc(s.c_str()).c_str()); new_string += "??"; new_string += sv[i].subString(2, sv[i].size()-2); } @@ -442,11 +444,10 @@ namespace StringUtils - '0' + delta; if (index >= all_vals.size()) { - fprintf(stderr, - "[StringUtils::insertValues] ERROR: " - "Invalid argument ID in '%s' : %i\n", - irr::core::stringc(s.c_str()).c_str(), - index); + Log::warn("StringUtils", "insertValues: " + "Invalid argument ID in '%s' : %i\n", + irr::core::stringc(s.c_str()).c_str(), + index); new_string += "??"; new_string += rest; } @@ -466,9 +467,9 @@ namespace StringUtils catch (std::exception& e) { (void)e; // avoid warning about unused variable - fprintf(stderr, - "Fatal error in insertValues(stringw) : %s @ line %i\n", - __FILE__, __LINE__); + Log::fatal("StringUtils", + "Fatal error in insertValues(stringw) : %s @ line %i.", + __FILE__, __LINE__); exit(1); } } @@ -599,10 +600,9 @@ namespace StringUtils } else { - fprintf(stderr, - "[StringUtils] WARNING: non-numeric HTML " - "entity not supported in '%s'\n", - input.c_str()); + Log::warn("StringUtils", "non-numeric HTML " + "entity not supported in '%s'.", + input.c_str()); } state = NORMAL; }