Refactored handling of rescue: this removed a lot of
duplicated code, and also allows non-race mode rescue positions to be tested in track-debug mode. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@13165 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
5e70f409af
commit
b20cebfee0
@ -416,37 +416,11 @@ bool CutsceneWorld::isRaceOver()
|
||||
return m_time > m_duration;
|
||||
} // isRaceOver
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called when the race finishes, i.e. after playing (if necessary) an
|
||||
* end of race animation. It updates the time for all karts still racing,
|
||||
* and then updates the ranks.
|
||||
*/
|
||||
void CutsceneWorld::terminateRace()
|
||||
{
|
||||
World::terminateRace();
|
||||
} // terminateRace
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the data to display in the race gui.
|
||||
*/
|
||||
void CutsceneWorld::getKartsDisplayInfo(
|
||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info)
|
||||
{
|
||||
} // getKartDisplayInfo
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Moves a kart to its rescue position.
|
||||
* \param kart The kart that was rescued.
|
||||
*/
|
||||
void CutsceneWorld::moveKartAfterRescue(AbstractKart* kart)
|
||||
{
|
||||
} // moveKartAfterRescue
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void CutsceneWorld::createRaceGUI()
|
||||
{
|
||||
m_race_gui = new CutsceneGUI();
|
||||
}
|
||||
} // createRaceGUI
|
||||
|
||||
|
||||
|
@ -68,17 +68,6 @@ public:
|
||||
|
||||
// clock events
|
||||
virtual bool isRaceOver() OVERRIDE;
|
||||
virtual void terminateRace() OVERRIDE;
|
||||
|
||||
void setParts(std::vector<std::string> parts)
|
||||
{
|
||||
m_parts = parts;
|
||||
}
|
||||
|
||||
virtual void getKartsDisplayInfo(
|
||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
|
||||
virtual bool raceHasLaps() OVERRIDE { return false; }
|
||||
virtual void moveKartAfterRescue(AbstractKart* kart) OVERRIDE;
|
||||
|
||||
virtual const std::string& getIdent() const OVERRIDE;
|
||||
|
||||
@ -88,8 +77,35 @@ public:
|
||||
|
||||
virtual void enterRaceOverState() OVERRIDE;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool raceHasLaps() OVERRIDE { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual unsigned int getNumberOfRescuePositions() const OVERRIDE
|
||||
{
|
||||
return 0;
|
||||
} // getNumberOfRescuePositions
|
||||
// ------------------------------------------------------------------------
|
||||
virtual unsigned int getRescuePositionIndex(AbstractKart *kart) OVERRIDE
|
||||
{
|
||||
return 0;
|
||||
} // getRescuePositionIndex
|
||||
// ------------------------------------------------------------------------
|
||||
virtual btTransform getRescueTransform(unsigned int index) const OVERRIDE
|
||||
{
|
||||
return btTransform();
|
||||
} // getRescueTransform
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void onFirePressed(Controller* who) OVERRIDE { abortCutscene(); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void setParts(std::vector<std::string> parts) { m_parts = parts; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the data to display in the race gui.
|
||||
*/
|
||||
virtual void getKartsDisplayInfo(
|
||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE
|
||||
{
|
||||
};
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void escapePressed() OVERRIDE { abortCutscene(); }
|
||||
|
||||
}; // CutsceneWorld
|
||||
|
@ -206,15 +206,3 @@ void EasterEggHunt::getKartsDisplayInfo(
|
||||
}
|
||||
} // getKartDisplayInfo
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Moves a kart to its rescue position.
|
||||
* \param kart The kart that was rescued.
|
||||
*/
|
||||
void EasterEggHunt::moveKartAfterRescue(AbstractKart* kart)
|
||||
{
|
||||
int start_position = kart->getInitialPosition();
|
||||
btTransform start_pos = getTrack()->getStartTransform(start_position-1);
|
||||
|
||||
kart->getBody()->setCenterOfMassTransform(start_pos);
|
||||
|
||||
} // moveKartAfterRescue
|
||||
|
@ -54,7 +54,6 @@ public:
|
||||
virtual void reset();
|
||||
|
||||
virtual bool raceHasLaps(){ return false; }
|
||||
virtual void moveKartAfterRescue(AbstractKart* kart);
|
||||
|
||||
virtual const std::string& getIdent() const;
|
||||
|
||||
|
@ -89,7 +89,7 @@ void LinearWorld::reset()
|
||||
for(unsigned int i=0; i<kart_amount; i++)
|
||||
{
|
||||
m_kart_info[i].reset();
|
||||
m_kart_info[i].getSector()->update(m_karts[i]->getXYZ());
|
||||
m_kart_info[i].getTrackSector()->update(m_karts[i]->getXYZ());
|
||||
} // next kart
|
||||
|
||||
// At the moment the last kart would be the one that is furthest away
|
||||
@ -172,7 +172,7 @@ void LinearWorld::update(float dt)
|
||||
// rescued or eliminated
|
||||
if(kart->getKartAnimation()) continue;
|
||||
|
||||
kart_info.getSector()->update(kart->getXYZ());
|
||||
kart_info.getTrackSector()->update(kart->getXYZ());
|
||||
kart_info.m_overall_distance = kart_info.m_race_lap
|
||||
* m_track->getTrackLength()
|
||||
+ getDistanceDownTrackForKart(kart->getWorldKartId());
|
||||
@ -376,7 +376,7 @@ int LinearWorld::getSectorForKart(const AbstractKart *kart) const
|
||||
{
|
||||
if(kart->getWorldKartId()>=m_kart_info.size())
|
||||
return QuadGraph::UNKNOWN_SECTOR;
|
||||
return m_kart_info[kart->getWorldKartId()].getSector()
|
||||
return m_kart_info[kart->getWorldKartId()].getTrackSector()
|
||||
->getCurrentGraphNode();
|
||||
} // getSectorForKart
|
||||
|
||||
@ -388,7 +388,7 @@ int LinearWorld::getSectorForKart(const AbstractKart *kart) const
|
||||
float LinearWorld::getDistanceDownTrackForKart(const int kart_id) const
|
||||
{
|
||||
assert(kart_id < (int)m_kart_info.size());
|
||||
return m_kart_info[kart_id].getSector()->getDistanceFromStart();
|
||||
return m_kart_info[kart_id].getTrackSector()->getDistanceFromStart();
|
||||
} // getDistanceDownTrackForKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -399,7 +399,7 @@ float LinearWorld::getDistanceDownTrackForKart(const int kart_id) const
|
||||
float LinearWorld::getDistanceToCenterForKart(const int kart_id) const
|
||||
{
|
||||
assert(kart_id < (int)m_kart_info.size());
|
||||
return m_kart_info[kart_id].getSector()->getDistanceToCenter();
|
||||
return m_kart_info[kart_id].getTrackSector()->getDistanceToCenter();
|
||||
} // getDistanceToCenterForKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -605,58 +605,37 @@ float LinearWorld::estimateFinishTimeForKart(AbstractKart* kart)
|
||||
return est_time;
|
||||
} // estimateFinishTimeForKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Decide where to drop a rescued kart
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the number of rescue positions on a given track, which in
|
||||
* linear races is just the number of driveline quads.
|
||||
*/
|
||||
void LinearWorld::moveKartAfterRescue(AbstractKart* kart)
|
||||
unsigned int LinearWorld::getNumberOfRescuePositions() const
|
||||
{
|
||||
return QuadGraph::get()->getNumNodes();
|
||||
} // getNumberOfRescuePositions
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
unsigned int LinearWorld::getRescuePositionIndex(AbstractKart *kart)
|
||||
{
|
||||
KartInfo& info = m_kart_info[kart->getWorldKartId()];
|
||||
|
||||
info.getSector()->rescue();
|
||||
info.getTrackSector()->rescue();
|
||||
// Setting XYZ for the kart is important since otherwise the kart
|
||||
// will not detect the right material again when doing the next
|
||||
// raycast to detect where it is driving on (--> 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;
|
||||
|
||||
|
@ -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<RaceGUIBase::KartIconDisplayInfo> *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
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -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<RaceGUIBase::KartIconDisplayInfo> *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; 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 = world->getTrack()->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
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#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<RaceGUIBase::KartIconDisplayInfo> *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;
|
||||
};
|
||||
|
||||
|
@ -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; 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 = world->getTrack()->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 = 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()
|
||||
{
|
||||
|
@ -64,7 +64,6 @@ public:
|
||||
virtual void getKartsDisplayInfo(
|
||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info);
|
||||
virtual bool raceHasLaps(){ return false; }
|
||||
virtual void moveKartAfterRescue(AbstractKart* kart);
|
||||
|
||||
virtual const std::string& getIdent() const;
|
||||
|
||||
|
@ -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; 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 = world->getTrack()->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; 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)
|
||||
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
|
||||
|
@ -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 <string>
|
||||
|
||||
#define CLEAR_SPAWN_RANGE 5
|
||||
|
||||
class PhysicalObject;
|
||||
|
||||
/**
|
||||
@ -99,7 +97,7 @@ public:
|
||||
virtual void getKartsDisplayInfo(
|
||||
std::vector<RaceGUIBase::KartIconDisplayInfo> *info);
|
||||
virtual bool raceHasLaps(){ return false; }
|
||||
virtual void moveKartAfterRescue(AbstractKart* kart);
|
||||
virtual unsigned int getRescuePositionIndex(AbstractKart *kart);
|
||||
|
||||
virtual const std::string& getIdent() const;
|
||||
|
||||
|
@ -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; 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 = world->getTrack()->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
|
@ -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
|
||||
|
@ -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; quad<QuadGraph::get()->getNumNodes(); 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_id<m_karts.size(); kart_id++)
|
||||
{
|
||||
AbstractKart *kart = m_karts[kart_id];
|
||||
kart->setXYZ(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*>(kart))
|
||||
dynamic_cast<Kart*>(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_id<m_karts.size()
|
||||
} // for quad < quad_graph.getNumNodes
|
||||
|
||||
// Loop over all karts, in case that some karts are dfferent
|
||||
for(unsigned int kart_id=0; kart_id<m_karts.size(); kart_id++)
|
||||
{
|
||||
for(unsigned int rescue_pos=0;
|
||||
rescue_pos<getNumberOfRescuePositions();
|
||||
rescue_pos++)
|
||||
{
|
||||
btTransform t = getRescueTransform(rescue_pos);
|
||||
// This will print out warnings if there is no terrain under
|
||||
// the kart, or the kart is being dropped on a reset texture
|
||||
moveKartTo(m_karts[kart_id], t);
|
||||
|
||||
} // rescue_pos<getNumberOfRescuePositions
|
||||
|
||||
// Reset the karts back to the original start position.
|
||||
// This call is a bit of an overkill, but setting the correct
|
||||
// transforms, positions, motion state is a bit of a hassle.
|
||||
m_karts[kart_id]->reset();
|
||||
}
|
||||
} // for kart_id<m_karts.size()
|
||||
|
||||
|
||||
} // if m_track_debug
|
||||
|
||||
|
||||
m_schedule_pause = false;
|
||||
m_schedule_unpause = false;
|
||||
|
||||
@ -546,13 +527,12 @@ void World::resetAllKarts()
|
||||
|
||||
if (!kart_over_ground)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -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; i<m_karts.size(); i++ )
|
||||
{
|
||||
fprintf(stderr, "i=%d position %d\n",i,
|
||||
m_karts[i]->getPosition());
|
||||
Log::error("World", "i=%d position %d.",i,
|
||||
m_karts[i]->getPosition());
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
|
@ -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. */
|
||||
|
@ -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 <iostream>
|
||||
|
||||
@ -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; n<start_spots_amount; n++)
|
||||
{
|
||||
const btTransform &s = getTrack()->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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** 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
|
||||
|
||||
|
@ -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 WorldWithRank::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
|
||||
|
Loading…
x
Reference in New Issue
Block a user