When returning to overworld, bring back player to approximately where they were upon leaving

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11067 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria
2012-04-01 17:17:36 +00:00
parent 74ab49b1ac
commit b83202439c
4 changed files with 91 additions and 1 deletions

View File

@@ -20,6 +20,7 @@
#include "input/input.hpp"
#include "input/input_manager.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "modes/overworld.hpp"
#include "network/network_manager.hpp"
@@ -59,7 +60,7 @@ void OverWorld::enterOverWorld()
// is read.
input_manager->getDeviceList()->setAssignMode(ASSIGN);
input_manager->getDeviceList()
->setSinglePlayer( StateManager::get()->getActivePlayer(0) );
->setSinglePlayer( StateManager::get()->getActivePlayer(0) );
StateManager::get()->enterGameState();
network_manager->setupPlayerKartInfo();
@@ -80,11 +81,21 @@ OverWorld::OverWorld() : LinearWorld()
void OverWorld::init()
{
LinearWorld::init();
if (race_manager->haveKartLastPositionOnOverworld())
{
AbstractKart* kart = m_karts[0];
kart->setXYZ(race_manager->getKartLastPositionOnOverworld());
moveKartAfterRescue(kart);
}
} // init
//-----------------------------------------------------------------------------
OverWorld::~OverWorld()
{
Vec3 kart_xyz = getKart(0)->getXYZ();
race_manager->setKartLastPositionOnOverworld(kart_xyz);
} // ~OverWorld
//-----------------------------------------------------------------------------
@@ -155,8 +166,73 @@ void OverWorld::onFirePressed(Controller* who)
if ((kart_xyz - Vec3(challenges[n].m_position)).length2_2d() < CHALLENGE_DISTANCE_SQUARED)
{
race_manager->setKartLastPositionOnOverworld(kart_xyz);
new SelectChallengeDialog(0.8f, 0.8f, challenges[n].m_challenge_id);
} // end if
} // end for
}
//-----------------------------------------------------------------------------
/** Moves a kart to its rescue position.
* \param kart The kart that was rescued.
*/
void OverWorld::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);
const float currentKart_x = kart->getXYZ().getX();
const float currentKart_z = kart->getXYZ().getZ();
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);
const btTransform &s = world->getTrack()->getStartTransform(closest_id);
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_physics->projectKartDownwards(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

View File

@@ -75,6 +75,8 @@ public:
virtual bool useChecklineRequirements() const { return false; }
// ------------------------------------------------------------------------
void scheduleReturnToGarage() { m_return_to_garage = true; }
// ------------------------------------------------------------------------
virtual void moveKartAfterRescue(AbstractKart* kart);
};
#endif

View File

@@ -57,6 +57,7 @@ RaceManager::RaceManager()
m_track_number = 0;
m_coin_target = 0;
m_started_from_overworld = false;
m_have_kart_last_position_on_overworld = false;
setReverseTrack(false);
setTrack("jungle");
m_default_ai_list.clear();

View File

@@ -33,6 +33,7 @@
#include "network/remote_kart_info.hpp"
#include "race/grand_prix_data.hpp"
#include "utils/translation.hpp"
#include "utils/vec3.hpp"
class AbstractKart;
class Track;
@@ -281,6 +282,8 @@ private:
left.m_overall_time > right.m_overall_time);
}
bool m_have_kart_last_position_on_overworld;
Vec3 m_kart_last_position_on_overworld;
public:
RaceManager();
@@ -538,6 +541,14 @@ public:
/** \} */
bool haveKartLastPositionOnOverworld() { return m_have_kart_last_position_on_overworld; }
void setKartLastPositionOnOverworld(Vec3 pos)
{
m_have_kart_last_position_on_overworld = true;
m_kart_last_position_on_overworld = pos;
}
Vec3 getKartLastPositionOnOverworld() { return m_kart_last_position_on_overworld; }
};
extern RaceManager *race_manager;