More refactoring: duplicated code handling track sectors and
distance along track is now moved into a separate class TrackSector and used in linear_world and rubber ball. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9422 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
428ed5a07b
commit
6e5086f9b8
@ -566,6 +566,8 @@ add_executable(supertuxkart
|
||||
src/tracks/track_object.hpp
|
||||
src/tracks/track_object_manager.cpp
|
||||
src/tracks/track_object_manager.hpp
|
||||
src/tracks/track_sector.cpp
|
||||
src/tracks/track_sector.hpp
|
||||
src/tutorial/tutorial.cpp
|
||||
src/tutorial/tutorial_data.cpp
|
||||
src/tutorial/tutorial_data.hpp
|
||||
|
@ -434,6 +434,8 @@ supertuxkart_SOURCES = \
|
||||
tracks/track_object.hpp \
|
||||
tracks/track_object_manager.cpp \
|
||||
tracks/track_object_manager.hpp \
|
||||
tracks/track_sector.cpp \
|
||||
tracks/track_sector.hpp \
|
||||
tutorial/tutorial.cpp \
|
||||
tutorial/tutorial.hpp \
|
||||
tutorial/tutorial_data.cpp \
|
||||
|
@ -874,6 +874,10 @@
|
||||
RelativePath="..\..\tracks\track_object_manager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\tracks\track_sector.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="replay"
|
||||
@ -1912,6 +1916,10 @@
|
||||
RelativePath="..\..\tracks\track_object_manager.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\tracks\track_sector.hpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="replay"
|
||||
|
@ -28,8 +28,9 @@ float RubberBall::m_st_interval;
|
||||
float RubberBall::m_st_squash_duration;
|
||||
float RubberBall::m_st_squash_slowdown;
|
||||
|
||||
RubberBall::RubberBall(Kart *kart) : Flyable(kart, PowerupManager::POWERUP_RUBBERBALL,
|
||||
0.0f /* mass */)
|
||||
RubberBall::RubberBall(Kart *kart)
|
||||
: Flyable(kart, PowerupManager::POWERUP_RUBBERBALL, 0.0f /* mass */),
|
||||
TrackSector()
|
||||
{
|
||||
float forw_offset = 0.5f*kart->getKartLength() + m_extend.getZ()*0.5f+5.0f;
|
||||
|
||||
@ -66,9 +67,11 @@ RubberBall::RubberBall(Kart *kart) : Flyable(kart, PowerupManager::POWERUP_RUBBE
|
||||
m_aiming_points[0] = QuadGraph::get()->getQuadOfNode(pred).getCenter();
|
||||
m_aiming_points[1] = QuadGraph::get()->getQuadOfNode(m_current_graph_node)
|
||||
.getCenter();
|
||||
m_aiming_points[2] = QuadGraph::get()->getQuadOfNode(m_aimed_graph_node).getCenter();
|
||||
m_aiming_points[2] = QuadGraph::get()->getQuadOfNode(m_aimed_graph_node)
|
||||
.getCenter();
|
||||
int succ_succ = getSuccessorToHitTarget(m_aimed_graph_node);
|
||||
m_aiming_points[3] = QuadGraph::get()->getQuadOfNode(succ_succ).getCenter();
|
||||
m_aiming_points[3] = QuadGraph::get()->getQuadOfNode(succ_succ)
|
||||
.getCenter();
|
||||
m_t = 0;
|
||||
m_t_increase = 1.0f/(m_aiming_points[2]-m_aiming_points[1]).length();
|
||||
|
||||
@ -172,6 +175,8 @@ void RubberBall::update(float dt)
|
||||
int indx = getSuccessorToHitTarget(m_current_graph_node);
|
||||
|
||||
// Determine new distance along track
|
||||
TrackSector::update(next_xyz);
|
||||
|
||||
Vec3 ball_distance_vec;
|
||||
QuadGraph::get()->findRoadSector(next_xyz, &m_current_graph_node);
|
||||
if(m_current_graph_node == QuadGraph::UNKNOWN_SECTOR)
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define HEADER_RUBBER_BALL_HPP
|
||||
|
||||
#include "items/flyable.hpp"
|
||||
#include "tracks/track_sector.hpp"
|
||||
|
||||
class Kart;
|
||||
class QuadGraph;
|
||||
@ -28,7 +29,7 @@ class QuadGraph;
|
||||
/**
|
||||
* \ingroup items
|
||||
*/
|
||||
class RubberBall: public Flyable
|
||||
class RubberBall: public Flyable, public TrackSector
|
||||
{
|
||||
private:
|
||||
/** A class variable to store the default interval size. */
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "network/network_manager.hpp"
|
||||
#include "race/history.hpp"
|
||||
#include "tracks/track_sector.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
@ -61,31 +62,7 @@ void LinearWorld::init()
|
||||
for(unsigned int n=0; n<kart_amount; n++)
|
||||
{
|
||||
KartInfo info;
|
||||
info.m_track_sector = QuadGraph::UNKNOWN_SECTOR;
|
||||
info.m_last_valid_sector = 0;
|
||||
info.m_lap_start_time = 0;
|
||||
QuadGraph::get()->findRoadSector(m_karts[n]->getXYZ(),
|
||||
&info.m_track_sector);
|
||||
|
||||
//If m_track_sector == UNKNOWN_SECTOR, then the kart is not on top of
|
||||
//the road, so we have to use another function to find the sector.
|
||||
info.m_on_road = info.m_track_sector != QuadGraph::UNKNOWN_SECTOR;
|
||||
if (!info.m_on_road)
|
||||
{
|
||||
info.m_track_sector =
|
||||
QuadGraph::get()->findOutOfRoadSector(m_karts[n]->getXYZ(),
|
||||
QuadGraph::UNKNOWN_SECTOR );
|
||||
}
|
||||
|
||||
QuadGraph::get()->spatialToTrack(&info.m_curr_track_coords,
|
||||
m_karts[n]->getXYZ(),
|
||||
info.m_track_sector );
|
||||
|
||||
info.m_race_lap = -1;
|
||||
info.m_lap_start_time = 0;
|
||||
info.m_time_at_last_lap = 99999.9f;
|
||||
info.m_estimated_finish = -1.0f;
|
||||
|
||||
info.getSector()->update(m_karts[n]->getXYZ());
|
||||
m_kart_info.push_back(info);
|
||||
} // next kart
|
||||
|
||||
@ -114,29 +91,8 @@ void LinearWorld::restartRace()
|
||||
const unsigned int kart_amount = m_karts.size();
|
||||
for(unsigned int i=0; i<kart_amount; i++)
|
||||
{
|
||||
KartInfo& info = m_kart_info[i];
|
||||
info.m_track_sector = QuadGraph::UNKNOWN_SECTOR;
|
||||
info.m_last_valid_sector = 0;
|
||||
info.m_lap_start_time = 0;
|
||||
QuadGraph::get()->findRoadSector(m_karts[i]->getXYZ(),
|
||||
&info.m_track_sector);
|
||||
|
||||
//If m_track_sector == UNKNOWN_SECTOR, then the kart is not on top of
|
||||
//the road, so we have to use another function to find the sector.
|
||||
info.m_on_road = info.m_track_sector != QuadGraph::UNKNOWN_SECTOR;
|
||||
if (!info.m_on_road)
|
||||
{
|
||||
info.m_track_sector =
|
||||
QuadGraph::get()->findOutOfRoadSector(m_karts[i]->getXYZ(),
|
||||
QuadGraph::UNKNOWN_SECTOR);
|
||||
}
|
||||
|
||||
QuadGraph::get()->spatialToTrack(&info.m_curr_track_coords,
|
||||
m_karts[i]->getXYZ(),
|
||||
info.m_track_sector );
|
||||
info.m_race_lap = -1;
|
||||
info.m_lap_start_time = -0;
|
||||
info.m_time_at_last_lap = 99999.9f;
|
||||
m_kart_info[i].reset();
|
||||
m_kart_info[i].getSector()->update(m_karts[i]->getXYZ());
|
||||
} // next kart
|
||||
|
||||
// First all kart infos must be updated before the kart position can be
|
||||
@ -193,30 +149,7 @@ void LinearWorld::update(float dt)
|
||||
// Nothing to do for karts that are currently being rescued or eliminated
|
||||
if(kart->playingEmergencyAnimation()) continue;
|
||||
|
||||
// ---------- deal with sector data ---------
|
||||
|
||||
// update sector variables
|
||||
int prev_sector = kart_info.m_track_sector;
|
||||
QuadGraph::get()->findRoadSector(kart->getXYZ(),
|
||||
&kart_info.m_track_sector);
|
||||
|
||||
kart_info.m_on_road = kart_info.m_track_sector != QuadGraph::UNKNOWN_SECTOR;
|
||||
if(kart_info.m_on_road)
|
||||
{
|
||||
kart_info.m_last_valid_sector = kart_info.m_track_sector;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Kart off road. Find the closest sector instead.
|
||||
kart_info.m_track_sector =
|
||||
QuadGraph::get()->findOutOfRoadSector(kart->getXYZ(), prev_sector );
|
||||
}
|
||||
|
||||
// Update track coords (=progression)
|
||||
QuadGraph::get()->spatialToTrack(&kart_info.m_curr_track_coords,
|
||||
kart->getXYZ(),
|
||||
kart_info.m_track_sector );
|
||||
|
||||
kart_info.getSector()->update(kart->getXYZ());
|
||||
} // for n
|
||||
|
||||
// Update all positions. This must be done after _all_ karts have
|
||||
@ -390,7 +323,7 @@ void LinearWorld::newLap(unsigned int kart_index)
|
||||
//-----------------------------------------------------------------------------
|
||||
int LinearWorld::getSectorForKart(const int kart_id) const
|
||||
{
|
||||
return m_kart_info[kart_id].m_track_sector;
|
||||
return m_kart_info[kart_id].getSector()->getCurrentGraphNode();
|
||||
} // getSectorForKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -400,7 +333,7 @@ int LinearWorld::getSectorForKart(const int kart_id) const
|
||||
*/
|
||||
float LinearWorld::getDistanceDownTrackForKart(const int kart_id) const
|
||||
{
|
||||
return m_kart_info[kart_id].m_curr_track_coords.getZ();
|
||||
return m_kart_info[kart_id].getSector()->getDistanceFromStart();
|
||||
} // getDistanceDownTrackForKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -410,7 +343,7 @@ float LinearWorld::getDistanceDownTrackForKart(const int kart_id) const
|
||||
*/
|
||||
float LinearWorld::getDistanceToCenterForKart(const int kart_id) const
|
||||
{
|
||||
return m_kart_info[kart_id].m_curr_track_coords.getX();
|
||||
return m_kart_info[kart_id].getSector()->getDistanceToCenter();
|
||||
} // getDistanceToCenterForKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -566,31 +499,13 @@ void LinearWorld::moveKartAfterRescue(Kart* kart)
|
||||
{
|
||||
KartInfo& info = m_kart_info[kart->getWorldKartId()];
|
||||
|
||||
// If the kart is off road, rescue it to the last valid track position
|
||||
// instead of the current one (since the sector might be determined by
|
||||
// being closest to it, which allows shortcuts like drive towards another
|
||||
// part of the lap, press rescue, and be rescued to this other part of
|
||||
// the track (example: math class, drive towards the left after start,
|
||||
// when hitting the books, press rescue --> you are rescued to the
|
||||
// end of the track).
|
||||
if(!info.m_on_road)
|
||||
{
|
||||
info.m_track_sector = info.m_last_valid_sector;
|
||||
}
|
||||
|
||||
// Using the predecessor has the additional afvantage (besides punishing
|
||||
// the player a bit more) that it makes it less likely to fall in a
|
||||
// rescue loop since the kart moves back on each attempt.
|
||||
info.m_track_sector = QuadGraph::get()->getNode(info.m_track_sector)
|
||||
.getPredecessor();
|
||||
info.m_last_valid_sector= QuadGraph::get()->getNode(info.m_track_sector)
|
||||
.getPredecessor();
|
||||
|
||||
kart->setXYZ( QuadGraph::get()->getQuadOfNode(info.m_track_sector)
|
||||
.getCenter());
|
||||
info.getSector()->rescue();
|
||||
int sector = info.getSector()->getCurrentGraphNode();
|
||||
kart->setXYZ( QuadGraph::get()
|
||||
->getQuadOfNode(sector).getCenter());
|
||||
|
||||
btQuaternion heading(btVector3(0.0f, 1.0f, 0.0f),
|
||||
m_track->getAngle(info.m_track_sector) );
|
||||
m_track->getAngle(sector) );
|
||||
kart->setRotation(heading);
|
||||
|
||||
// A certain epsilon is added here to the Z coordinate, in case
|
||||
@ -602,7 +517,7 @@ void LinearWorld::moveKartAfterRescue(Kart* kart)
|
||||
btTransform pos;
|
||||
pos.setOrigin(kart->getXYZ()+btVector3(0, kart->getKartHeight() + epsilon, 0));
|
||||
pos.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f),
|
||||
m_track->getAngle(info.m_track_sector)));
|
||||
m_track->getAngle(sector)));
|
||||
|
||||
kart->getBody()->setCenterOfMassTransform(pos);
|
||||
|
||||
@ -815,19 +730,20 @@ void LinearWorld::updateRacePosition()
|
||||
void LinearWorld::checkForWrongDirection(unsigned int i)
|
||||
{
|
||||
if(!m_karts[i]->getController()->isPlayerController()) return;
|
||||
if(!m_kart_info[i].m_on_road ||
|
||||
if(!m_kart_info[i].getSector()->isOnRoad()||
|
||||
m_karts[i]->playingEmergencyAnimation()) return;
|
||||
|
||||
const Kart *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.
|
||||
if(QuadGraph::get()->getNumberOfSuccessors(m_kart_info[i].m_track_sector)>1)
|
||||
int sector = m_kart_info[i].getSector()->getCurrentGraphNode();
|
||||
if(QuadGraph::get()->getNumberOfSuccessors(sector)>1)
|
||||
return;
|
||||
|
||||
// check if the player is going in the wrong direction
|
||||
float angle_diff = kart->getHeading() -
|
||||
m_track->getAngle(m_kart_info[i].m_track_sector);
|
||||
m_track->getAngle(sector);
|
||||
if(angle_diff > M_PI) angle_diff -= 2*M_PI;
|
||||
else if (angle_diff < -M_PI) angle_diff += 2*M_PI;
|
||||
// Display a warning message if the kart is going back way (unless
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "modes/world_with_rank.hpp"
|
||||
#include "tracks/track_sector.hpp"
|
||||
#include "utils/aligned_array.hpp"
|
||||
|
||||
class SFXBase;
|
||||
@ -33,6 +34,7 @@ class SFXBase;
|
||||
*/
|
||||
class LinearWorld : public WorldWithRank
|
||||
{
|
||||
private:
|
||||
/** Sfx for the final lap. */
|
||||
SFXBase *m_last_lap_sfx;
|
||||
|
||||
@ -41,27 +43,48 @@ class LinearWorld : public WorldWithRank
|
||||
|
||||
bool m_last_lap_sfx_playing;
|
||||
|
||||
private:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Some additional info that needs to be kept for each kart
|
||||
* in this kind of race.
|
||||
*/
|
||||
struct KartInfo
|
||||
class KartInfo
|
||||
{
|
||||
int m_race_lap; /**<Number of finished(!) laps. */
|
||||
float m_time_at_last_lap; /**<Time at finishing last lap. */
|
||||
float m_lap_start_time; /**<Time at start of a new lap. */
|
||||
float m_estimated_finish; /**<During last lap only:
|
||||
* estimated finishing time! */
|
||||
int m_track_sector; /**<Index in driveline, special values
|
||||
* e.g. UNKNOWN_SECTOR can be negative!*/
|
||||
public:
|
||||
/** Number of finished(!) laps. */
|
||||
int m_race_lap;
|
||||
|
||||
int m_last_valid_sector; /* used when rescusing, e.g. for invalid shortcuts */
|
||||
/** Time at finishing last lap. */
|
||||
float m_time_at_last_lap;
|
||||
|
||||
Vec3 m_curr_track_coords;
|
||||
/** True if the kart is on top of the road path drawn by the drivelines */
|
||||
bool m_on_road;
|
||||
/** Time at start of a new lap. */
|
||||
float m_lap_start_time;
|
||||
|
||||
/** During last lap only: estimated finishing time! */
|
||||
float m_estimated_finish;
|
||||
|
||||
/** Stores the current graph node and track coordinates etc. */
|
||||
TrackSector m_current_sector;
|
||||
|
||||
/** Initialises all fields. */
|
||||
KartInfo() { reset(); }
|
||||
// --------------------------------------------------------------------
|
||||
/** Re-initialises all data. */
|
||||
void reset()
|
||||
{
|
||||
m_race_lap = -1;
|
||||
m_lap_start_time = 0;
|
||||
m_time_at_last_lap = 99999.9f;
|
||||
m_estimated_finish = -1.0f;
|
||||
m_current_sector.reset();
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns a pointer to the current node object. */
|
||||
TrackSector *getSector() {return &m_current_sector; }
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns a pointer to the current node object. */
|
||||
const TrackSector *getSector() const {return &m_current_sector; }
|
||||
};
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
protected:
|
||||
RaceGUIBase::KartIconDisplayInfo* m_kart_display_info;
|
||||
@ -101,17 +124,19 @@ public:
|
||||
getKartsDisplayInfo();
|
||||
virtual void moveKartAfterRescue(Kart* kart);
|
||||
virtual void restartRace();
|
||||
|
||||
virtual bool raceHasLaps(){ return true; }
|
||||
virtual void newLap(unsigned int kart_index);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if this race mode has laps. */
|
||||
virtual bool raceHasLaps(){ return true; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if this race mode has bonus items. */
|
||||
virtual bool haveBonusBoxes(){ return true; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if the kart is on a valid driveline quad.
|
||||
* \param kart_index Index of the kart.
|
||||
*/
|
||||
* \param kart_index Index of the kart. */
|
||||
bool isOnRoad(unsigned int kart_index) const
|
||||
{ return m_kart_info[kart_index].m_on_road; }
|
||||
{ return m_kart_info[kart_index].getSector()->isOnRoad(); }
|
||||
}; // LinearWorld
|
||||
|
||||
#endif
|
||||
|
@ -516,12 +516,9 @@ void QuadGraph::spatialToTrack(Vec3 *dst, const Vec3& xyz,
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** findRoadSector returns in which sector on the road the position
|
||||
* xyz is. If xyz is not on top of the road, it returns
|
||||
* UNKNOWN_SECTOR.
|
||||
* xyz is. If xyz is not on top of the road, it sets UNKNOWN_SECTOR as sector.
|
||||
*
|
||||
* The 'sector' could be defined as the number of the closest track
|
||||
* segment to XYZ.
|
||||
* \param XYZ Position for which the segment should be determined.
|
||||
* \param xyz Position for which the segment should be determined.
|
||||
* \param sector Contains the previous sector (as a shortcut, since usually
|
||||
* the sector is the same as the last one), and on return the result
|
||||
* \param all_sectors If this is not NULL, it is a list of all sectors to
|
||||
@ -565,7 +562,7 @@ void QuadGraph::findRoadSector(const Vec3& xyz, int *sector,
|
||||
indx = indx<(int)m_all_nodes.size()-1 ? indx +1 : 0;
|
||||
const Quad &q = getQuadOfNode(indx);
|
||||
float dist = xyz.getY() - q.getMinHeight();
|
||||
// While negative distances are unlikely, we allow some small netative
|
||||
// While negative distances are unlikely, we allow some small negative
|
||||
// numbers in case that the kart is partly in the track.
|
||||
if(q.pointInQuad(xyz) && dist < min_dist && dist>-1.0f)
|
||||
{
|
||||
|
91
src/tracks/track_sector.cpp
Normal file
91
src/tracks/track_sector.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
// $Id$
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 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 "tracks/track_sector.hpp"
|
||||
#include "tracks/quad_graph.hpp"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Initialises the object, and sets the current graph node to be undefined.
|
||||
*/
|
||||
TrackSector::TrackSector()
|
||||
{
|
||||
reset();
|
||||
} // TrackSector
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void TrackSector::reset()
|
||||
{
|
||||
m_current_graph_node = QuadGraph::UNKNOWN_SECTOR;
|
||||
m_last_valid_graph_node = QuadGraph::UNKNOWN_SECTOR;
|
||||
m_on_road = false;
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Updates the current graph node index, and the track coordinates for
|
||||
* the specified point.
|
||||
* \param xyz The new coordinates to search the graph node for.
|
||||
*/
|
||||
void TrackSector::update(const Vec3 &xyz)
|
||||
{
|
||||
int prev_sector = m_current_graph_node;
|
||||
|
||||
QuadGraph::get()->findRoadSector(xyz, &m_current_graph_node);
|
||||
m_on_road = m_current_graph_node != QuadGraph::UNKNOWN_SECTOR;
|
||||
|
||||
// If m_track_sector == UNKNOWN_SECTOR, then the kart is not on top of
|
||||
// the road, so we have to use search for the closest graph node.
|
||||
if(m_current_graph_node == QuadGraph::UNKNOWN_SECTOR)
|
||||
{
|
||||
m_current_graph_node =
|
||||
QuadGraph::get()->findOutOfRoadSector(xyz,
|
||||
prev_sector);
|
||||
}
|
||||
else
|
||||
m_last_valid_graph_node = m_current_graph_node;
|
||||
|
||||
// Now determine the 'track' coords, i.e. ow far from the start of the
|
||||
// track, and how far to the left or right of the center driveline.
|
||||
QuadGraph::get()->spatialToTrack(&m_current_track_coords, xyz,
|
||||
m_current_graph_node);
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void TrackSector::rescue()
|
||||
{
|
||||
// If the kart is off road, rescue it to the last valid track position
|
||||
// instead of the current one (since the sector might be determined by
|
||||
// being closest to it, which allows shortcuts like drive towards another
|
||||
// part of the lap, press rescue, and be rescued to this other part of
|
||||
// the track (example: math class, drive towards the left after start,
|
||||
// when hitting the books, press rescue --> you are rescued to the
|
||||
// end of the track).
|
||||
if(!isOnRoad())
|
||||
{
|
||||
m_current_graph_node = m_last_valid_graph_node;
|
||||
}
|
||||
|
||||
// Using the predecessor has the additional advantage (besides punishing
|
||||
// the player a bit more) that it makes it less likely to fall in a
|
||||
// rescue loop since the kart moves back on each attempt.
|
||||
m_current_graph_node = QuadGraph::get()->getNode(m_current_graph_node)
|
||||
.getPredecessor();
|
||||
m_last_valid_graph_node = QuadGraph::get()->getNode(m_current_graph_node)
|
||||
.getPredecessor();
|
||||
} // rescue
|
75
src/tracks/track_sector.hpp
Normal file
75
src/tracks/track_sector.hpp
Normal file
@ -0,0 +1,75 @@
|
||||
// $Id$
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 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_TRACK_SECTOR_HPP
|
||||
#define HEADER_TRACK_SECTOR_HPP
|
||||
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
/** This object keeps track of which sector an object is on. A sector is
|
||||
* actually just the graph node (it's called sector to better distinguish
|
||||
* the graph node from say xml node and scene node).
|
||||
* An object that has a track sector can determine how far away it is from
|
||||
* the start line, how far away it is from the center driveline. If the
|
||||
* object is not actually on part of the quad graph, it will determine the
|
||||
* closest sector it is to, and set a flag (!isOnRoad).
|
||||
* This object will also keep track on the last valid sector an object was
|
||||
* on, which is used to reset a kart in case of a rescue.
|
||||
|
||||
*/
|
||||
class TrackSector
|
||||
{
|
||||
private:
|
||||
/** The graph node the object is on. */
|
||||
int m_current_graph_node;
|
||||
|
||||
/** The index of the last valid graph node. */
|
||||
int m_last_valid_graph_node;
|
||||
|
||||
/** The coordinates of this object on the track, i.e. how far from
|
||||
* the start of the track, and how far to the left or right
|
||||
* of the center driveline. */
|
||||
Vec3 m_current_track_coords;
|
||||
|
||||
/** True if the object is on the road (driveline), or not. */
|
||||
bool m_on_road;
|
||||
|
||||
|
||||
public:
|
||||
TrackSector();
|
||||
void reset();
|
||||
void rescue();
|
||||
void update(const Vec3 &xyz);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how far the the object is from the start line. */
|
||||
float getDistanceFromStart() const { return m_current_track_coords.getZ();}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the distance to the centre driveline. */
|
||||
float getDistanceToCenter() const { return m_current_track_coords.getX(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the current graph node. */
|
||||
int getCurrentGraphNode() const {return m_current_graph_node;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if this object is on the road (driveline). */
|
||||
bool isOnRoad() const { return m_on_road; }
|
||||
|
||||
}; // TrackSector
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user