Merging with trunk, aesthetic changes, and added virtual keyword to the destructor of Track_object.hpp because of errors.

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/uni@13376 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
unitraxx 2013-07-28 17:27:06 +00:00
commit 1d90f554e8
48 changed files with 629 additions and 703 deletions

View File

@ -12,7 +12,7 @@
<spacer height="20" width="50">
<buttonbar id="options" width="25%" proportion="1" align="center">
<buttonbar id="options" width="25%" height="15%" align="center">
<icon-button id="cancel" width="64" height="64" icon="gui/green_check.png"
I18N="Registration dialog" text="Close" label_location="none"/>
</buttonbar>

View File

@ -2,7 +2,7 @@
<div x="2%" y="5%" width="96%" height="90%" layout="vertical-row" >
<header id="title" width="96%" proportion="1" text_align="center" word_wrap="true"
<header id="title" width="96%" height="fit" text_align="center" word_wrap="true"
I18N="In the registration dialog' dialog" text="Registration Complete"/>
<spacer height="20" width="50">
@ -12,7 +12,7 @@
<spacer height="20" width="50">
<buttonbar id="options" width="25%" proportion="1" align="center">
<buttonbar id="options" width="25%" height="15%" align="center">
<icon-button id="cancel" width="64" height="64" icon="gui/green_check.png"
I18N="Registration dialog" text="Close" label_location="none"/>
</buttonbar>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -147,6 +147,12 @@
<camera distance="1.5" forward-up-angle="15"
backward-up-angle="30"/>
<!-- Jump animation related values:
animation-time: only if the estimated time for a jump is larger
than this value will the jump animation being
shown. -->
<jump animation-time="0.5" />
<!-- If a kart starts within the specified time after 'go',
it receives the corresponding bonus from 'boost'. Those
fields must have the same size, and must be sorted by

View File

@ -43,14 +43,6 @@
#include "utils/time.hpp"
#include "utils/translation.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
// Use Sleep, which takes time in msecs. It must be defined after the
// includes, since otherwise irrlicht's sleep function is changed.
# define sleep(s) Sleep(1000*(s))
#else
# include <unistd.h>
#endif
// ----------------------------------------------------------------------------
/** Create a thread that handles all network functions independent of the
* main program. NetworkHttp supports only a single thread (i.e. it's not

View File

@ -1266,23 +1266,6 @@ void IrrDriver::displayFPS()
const int NO_TRUST_COUNT = 200;
static int no_trust = NO_TRUST_COUNT;
if (no_trust)
{
no_trust--;
static video::SColor fpsColor = video::SColor(255, 255, 0, 0);
font->draw( L"FPS: ...", core::rect< s32 >(100,0,400,50), fpsColor,
false );
return;
}
// Ask for current frames per second and last number of triangles
// processed (trimed to thousands)
const int fps = m_video_driver->getFPS();
const float kilotris = m_video_driver->getPrimitiveCountDrawn(0)
* (1.f / 1000.f);
// Min and max info tracking, per mode, so user can check game vs menus
bool current_state = StateManager::get()->getGameState()
== GUIEngine::GAME;
@ -1303,6 +1286,23 @@ void IrrDriver::displayFPS()
prev_state = current_state;
}
if (no_trust)
{
no_trust--;
static video::SColor fpsColor = video::SColor(255, 255, 0, 0);
font->draw( L"FPS: ...", core::rect< s32 >(100,0,400,50), fpsColor,
false );
return;
}
// Ask for current frames per second and last number of triangles
// processed (trimed to thousands)
const int fps = m_video_driver->getFPS();
const float kilotris = m_video_driver->getPrimitiveCountDrawn(0)
* (1.f / 1000.f);
if (min > fps && fps > 1) min = fps; // Start moments sometimes give useless 1
if (max < fps) max = fps;
if (low > kilotris) low = kilotris;
@ -1863,17 +1863,15 @@ void IrrDriver::RTTProvider::setupRTTScene(PtrVector<scene::IMesh, REF>& mesh,
}
}
irr_driver->getSceneManager()->setAmbientLight(video::SColor(255, 120,
120, 120) );
irr_driver->getSceneManager()->setAmbientLight(video::SColor(255, 10, 10, 10) );
const core::vector3df &sun_pos = core::vector3df( 0, 200, 100.0f );
const core::vector3df &spot_pos = core::vector3df(30, 30, 30);
m_light = irr_driver->getSceneManager()
->addLightSceneNode(NULL, sun_pos, video::SColorf(1.0f,1.0f,1.0f),
10000.0f /* radius */);
m_light->getLightData().DiffuseColor
= video::SColorf(0.5f, 0.5f, 0.5f, 0.5f);
m_light->getLightData().SpecularColor
= video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
->addLightSceneNode(NULL, spot_pos, video::SColorf(1.0f,1.0f,1.0f),
1600 /* radius */);
m_light->setLightType(video::ELT_SPOT);
m_light->setRotation((core::vector3df(0, 10, 0) - spot_pos).getHorizontalAngle());
m_light->updateAbsolutePosition();
m_rtt_main_node->setMaterialFlag(video::EMF_GOURAUD_SHADING , true);
m_rtt_main_node->setMaterialFlag(video::EMF_LIGHTING, true);

View File

@ -483,6 +483,7 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
node->get("mask", &m_mask );
node->get("water-splash", &m_water_splash );
node->get("jump", &m_is_jump_texture );
if (m_collision_reaction != NORMAL)
{
@ -732,6 +733,7 @@ void Material::init(unsigned int index)
m_is_heightmap = false;
m_alpha_to_coverage = false;
m_water_splash = false;
m_is_jump_texture = false;
m_shaders.resize(SHADER_COUNT, NULL);

View File

@ -114,11 +114,16 @@ private:
* surface is not a physical object), but the location of the water
* effect is on the surface. */
bool m_surface;
/** If the material is a zipper, i.e. gives a speed boost. */
bool m_zipper;
/** If a kart is rescued when driving on this surface. */
bool m_drive_reset;
/** True if this is a texture that will start the jump animatoin when
* leaving it and being in the air. */
bool m_is_jump_texture;
/** Speed of the 'main' wave in the water shader. Only used if
m_graphical_effect == WATER_SHADER */
@ -321,6 +326,10 @@ public:
* the special falling camera. */
bool hasFallingEffect() const {return m_falling_effect; }
// ------------------------------------------------------------------------
/** Returns if being in the air after this texture should start the
* jump animation. */
bool isJumpTexture() const { return m_is_jump_texture; }
// ------------------------------------------------------------------------
/** Returns the zipper parametersfor the current material. */
void getZipperParameter(float *zipper_max_speed_increase,
float *zipper_duration,

View File

@ -531,6 +531,7 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID,
else if (button == KEY_RIGHT) action = PA_MENU_RIGHT;
else if (button == KEY_SPACE) action = PA_MENU_SELECT;
else if (button == KEY_RETURN) action = PA_MENU_SELECT;
else if (button == KEY_TAB) action = PA_MENU_DOWN;
if (button == KEY_RETURN && GUIEngine::ModalDialog::isADialogActive())
{

View File

@ -854,10 +854,8 @@ void FileManager::redirectOutput()
{
//Enable logging of stdout and stderr to logfile
std::string logoutfile = getLogFile("stdout.log");
std::string logerrfile = getLogFile("stderr.log");
Log::verbose("main", "Error messages and other text output will "
"be logged to %s and %s.", logoutfile.c_str(),
logerrfile.c_str());
"be logged to %s.", logoutfile.c_str());
Log::openOutputFiles(logoutfile);
} // redirectOutput

View File

@ -597,4 +597,4 @@ bool XMLNode::hasChildNamed(const char* name) const
if (m_nodes[i]->getName() == name) return true;
}
return false;
}
}

View File

@ -317,6 +317,11 @@ public:
// ------------------------------------------------------------------------
virtual void setEnergy(float val) = 0;
// ------------------------------------------------------------------------
/** Return whether nitro is being used despite the nitro button not being
* pressed due to minimal use time requirements
*/
virtual float isOnMinNitroTime() const = 0;
// ------------------------------------------------------------------------
/** Returns the current material the kart is on. */
virtual const Material *getMaterial() const = 0;
// ------------------------------------------------------------------------

View File

@ -119,10 +119,10 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
m_flying = false;
m_sky_particles_emitter= NULL;
m_stars_effect = NULL;
m_timeFlying = 0;
m_isTimeFlying = false;
m_hitGround = NULL;
m_jump_time = 0;
m_is_jumping = false;
m_min_nitro_time = 0.0f;
m_view_blocked_by_plunger = 0;
m_has_caught_nolok_bubblegum = false;
@ -295,6 +295,8 @@ void Kart::reset()
if(m_body)
World::getWorld()->getPhysics()->addKart(this);
m_min_nitro_time = 0.0f;
// Reset star effect in case that it is currently being shown.
m_stars_effect->reset();
m_max_speed->reset();
@ -339,6 +341,8 @@ void Kart::reset()
m_bubblegum_time = 0.0f;
m_bubblegum_torque = 0.0f;
m_has_caught_nolok_bubblegum = false;
m_is_jumping = false;
// In case that the kart was in the air, in which case its
// linear damping is 0
m_body->setDamping(m_kart_properties->getChassisLinearDamping(),
@ -1198,17 +1202,39 @@ void Kart::update(float dt)
// values for the raycasts).
if (!isOnGround())
{
m_timeFlying+=dt;
m_isTimeFlying = true;
const Material *m = getMaterial();
const Material *last_m = getLastMaterial();
// A jump starts only the kart isn't already jumping, is on a new
// (or no) texture.
if(!m_is_jumping && last_m && last_m!=m )
{
float v = getVelocity().getY();
float force = World::getWorld()->getTrack()->getGravity();;
// Velocity / force is the time it takes to reach the peak
// of the jump (i.e. when vertical speed becomes 0). Assuming
// that jump start height and end height are the same, it will
// take the same time again to reach the bottom
float t = 2.0f * v/force;
// Jump if either the jump is estimated to be long enough, or
// the texture has the jump property set.
if(t>getKartProperties()->getJumpAnimationTime() ||
last_m->isJumpTexture() )
m_kart_model->setAnimation(KartModel::AF_JUMP_START);
m_is_jumping = true;
}
m_jump_time+=dt;
}
if(isOnGround() && m_isTimeFlying)
else if (m_is_jumping)
{
m_isTimeFlying = false;
m_hitGround = new Explosion(getXYZ(), "jump",
"jump_explosion.xml");
projectile_manager->addHitEffect(m_hitGround);
m_timeFlying = 0;
// Kart touched ground again
m_is_jumping = false;
HitEffect *effect = new Explosion(getXYZ(), "jump",
"jump_explosion.xml");
projectile_manager->addHitEffect(effect);
m_kart_model->setAnimation(KartModel::AF_DEFAULT);
m_jump_time = 0;
}
if( (!isOnGround() || emergency) && m_shadow_enabled)
@ -1508,18 +1534,40 @@ void Kart::handleZipper(const Material *material, bool play_sound)
*/
void Kart::updateNitro(float dt)
{
if(!m_controls.m_nitro || !isOnGround()) return;
if (m_controls.m_nitro && m_min_nitro_time <= 0.0f)
{
m_min_nitro_time = m_kart_properties->getNitroMinConsumptionTime();
}
if (m_min_nitro_time > 0.0f)
{
m_min_nitro_time -= dt;
// when pressing the key, don't allow the min time to go under zero.
// If it went under zero, it would be reset
if (m_controls.m_nitro && m_min_nitro_time <= 0.0f)
m_min_nitro_time = 0.1f;
}
bool increase_speed = (m_controls.m_nitro && isOnGround());
if (!increase_speed && m_min_nitro_time <= 0.0f)
{
return;
}
m_collected_energy -= dt * m_kart_properties->getNitroConsumption();
if(m_collected_energy<0)
if (m_collected_energy < 0)
{
m_collected_energy = 0;
return;
}
m_max_speed->increaseMaxSpeed(MaxSpeed::MS_INCREASE_NITRO,
m_kart_properties->getNitroMaxSpeedIncrease(),
m_kart_properties->getNitroEngineForce(),
m_kart_properties->getNitroDuration(),
m_kart_properties->getNitroFadeOutTime() );
if (increase_speed)
{
m_max_speed->increaseMaxSpeed(MaxSpeed::MS_INCREASE_NITRO,
m_kart_properties->getNitroMaxSpeedIncrease(),
m_kart_properties->getNitroEngineForce(),
m_kart_properties->getNitroDuration(),
m_kart_properties->getNitroFadeOutTime() );
}
} // updateNitro
// -----------------------------------------------------------------------------
@ -2254,7 +2302,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
y += m_skidding->getGraphicalJumpOffset();
center_shift.setY(y);
if (m_controls.m_nitro && isOnGround() && m_collected_energy > 0)
if ((m_controls.m_nitro || m_min_nitro_time > 0.0f) && isOnGround() && m_collected_energy > 0)
{
// fabs(speed) is important, otherwise the negative number will
// become a huge unsigned number in the particle scene node!

View File

@ -41,6 +41,7 @@ class Attachment;
class Controller;
class Item;
class AbstractKartAnimation;
class HitEffect;
class KartGFX;
class MaxSpeed;
class ParticleEmitter;
@ -51,7 +52,6 @@ class Skidding;
class SkidMarks;
class SlipStream;
class Stars;
class HitEffect;
/** The main kart class. All type of karts are of this object, but with
* different controllers. The controllers are what turn a kart into a
@ -149,14 +149,11 @@ private:
// Graphical effects
// -----------------
/** The time where a kart is flying */
float m_timeFlying;
/** For the effect when the kart touch the ground */
HitEffect *m_hitGround;
/** Time a kart is jumping. */
float m_jump_time;
/** Is time flying activated */
bool m_isTimeFlying;
bool m_is_jumping;
/** The shadow of a kart. */
Shadow *m_shadow;
@ -210,6 +207,9 @@ private:
SFXBase *m_skid_sound;
SFXBase *m_goo_sound;
float m_time_last_crash;
/** To prevent using nitro in too short bursts */
float m_min_nitro_time;
void updatePhysics(float dt);
void handleMaterialSFX(const Material *material);
@ -403,6 +403,11 @@ public:
/** Sets the energy the kart has collected. */
virtual void setEnergy(float val) { m_collected_energy = val; }
// ------------------------------------------------------------------------
/** Return whether nitro is being used despite the nitro button not being
* pressed due to minimal use time requirements
*/
virtual float isOnMinNitroTime() const { return m_min_nitro_time > 0.0f; }
// ------------------------------------------------------------------------
/** Returns if the kart is currently being squashed. */
virtual bool isSquashed() const { return m_squash_time >0; }
// ------------------------------------------------------------------------

View File

@ -120,6 +120,9 @@ void KartModel::loadInfo(const XMLNode &node)
animation_node->get("end-losing", &m_animation_frame[AF_LOSE_END] );
animation_node->get("start-explosion",&m_animation_frame[AF_LOSE_START]);
animation_node->get("end-explosion", &m_animation_frame[AF_LOSE_END] );
animation_node->get("start-jump", &m_animation_frame[AF_JUMP_START]);
animation_node->get("start-jump-loop",&m_animation_frame[AF_JUMP_LOOP] );
animation_node->get("end-jump", &m_animation_frame[AF_JUMP_END] );
animation_node->get("speed", &m_animation_speed );
}
@ -130,14 +133,6 @@ void KartModel::loadInfo(const XMLNode &node)
loadWheelInfo(*wheels_node, "rear-right", 2);
loadWheelInfo(*wheels_node, "rear-left", 3);
}
// FIXME fallback for karts that don't have nitro emitter
/*
m_nitro_emitter_position[0] = Vec3 (0, m_kart_height*0.35f,
-m_kart_length*0.35f);
m_nitro_emitter_position[1] = Vec3 (0, m_kart_height*0.35f,
-m_kart_length*0.35f); */
m_nitro_emitter_position[0] = Vec3 (0,0.1f,0);
@ -569,6 +564,8 @@ void KartModel::setAnimation(AnimationFrameType type)
// 'type' is the start frame of the animation, type + 1 the frame
// to begin the loop with, type + 2 to end the frame with
AnimationFrameType end = (AnimationFrameType)(type+2);
if(m_animation_frame[end]==-1)
end = (AnimationFrameType)((int)end-1);
m_animated_node->setAnimationSpeed(m_animation_speed);
m_animated_node->setFrameLoop(m_animation_frame[type],
m_animation_frame[end] );
@ -613,10 +610,16 @@ void KartModel::OnAnimationEnd(scene::IAnimatedMeshSceneNode *node)
if(m_animation_frame[start]==-1)
start = m_current_animation;
AnimationFrameType end = (AnimationFrameType)(m_current_animation+2);
m_animated_node->setAnimationSpeed(m_animation_speed);
m_animated_node->setFrameLoop(m_animation_frame[start],
m_animation_frame[end] );
m_animated_node->setLoopMode(true);
// Switch to loop mode if the current animation has a loop defined
// (else just disable the callback, and the last frame will be shown).
if(m_animation_frame[end]>-1)
{
m_animated_node->setAnimationSpeed(m_animation_speed);
m_animated_node->setFrameLoop(m_animation_frame[start],
m_animation_frame[end] );
m_animated_node->setLoopMode(true);
}
m_animated_node->setAnimationEndCallback(NULL);
} // OnAnimationEnd

View File

@ -60,6 +60,9 @@ public:
AF_LOSE_END, // End losing animation
AF_BEGIN_EXPLOSION, // Begin explosion animation
AF_END_EXPLOSION, // End explosion animation
AF_JUMP_START, // Begin of jump
AF_JUMP_LOOP, // Begin of jump loop
AF_JUMP_END, // End of jump
AF_WIN_START, // Begin of win animation
AF_WIN_LOOP_START, // Begin of win loop animation
AF_WIN_END, // End of win animation

View File

@ -90,7 +90,8 @@ KartProperties::KartProperties(const std::string &filename)
m_swatter_distance2 = m_swatter_duration = m_squash_slowdown =
m_squash_duration = m_downward_impulse_factor =
m_bubblegum_fade_in_time = m_bubblegum_speed_fraction =
m_bubblegum_time = m_bubblegum_torque = UNDEFINED;
m_bubblegum_time = m_bubblegum_torque = m_jump_animation_time =
UNDEFINED;
m_engine_power.resize(RaceManager::DIFFICULTY_COUNT, UNDEFINED);
m_max_speed.resize(RaceManager::DIFFICULTY_COUNT, UNDEFINED);
@ -107,6 +108,7 @@ KartProperties::KartProperties(const std::string &filename)
m_engine_sfx_type = "engine_small";
m_kart_model = NULL;
m_has_rand_wheels = false;
m_nitro_min_consumption = 1.0f;
// The default constructor for stk_config uses filename=""
if (filename != "")
{
@ -312,6 +314,7 @@ void KartProperties::getAllData(const XMLNode * root)
nitro_node->get("duration", &m_nitro_duration );
nitro_node->get("fade-out-time", &m_nitro_fade_out_time );
nitro_node->get("max", &m_nitro_max );
nitro_node->get("min-consumption-time", &m_nitro_min_consumption );
}
if(const XMLNode *bubble_node = root->getNode("bubblegum"))
@ -519,6 +522,11 @@ void KartProperties::getAllData(const XMLNode * root)
m_lean_speed *= DEGREE_TO_RAD;
}
if(const XMLNode *jump_node= root->getNode("jump"))
{
jump_node->get("animation-time", &m_jump_animation_time);
}
if(const XMLNode *camera_node= root->getNode("camera"))
{
camera_node->get("distance", &m_camera_distance);

View File

@ -176,6 +176,11 @@ private:
/** Vertical offset after rescue. */
float m_rescue_vert_offset;
/** Minimum time during which nitro is consumed when pressing
* the nitro key (to prevent using in very small bursts)
*/
float m_nitro_min_consumption;
/** Filename of the wheel models. */
std::string m_wheel_filename[4];
/** Radius of the graphical wheels. */
@ -243,6 +248,9 @@ private:
* (in radians/second). */
float m_lean_speed;
/** How long a jump must be in order to trigger the jump animation. */
float m_jump_animation_time;
/** Engine sound effect. */
std::string m_engine_sfx_type;
@ -844,9 +852,17 @@ public:
/** The speed with which a kart should lean (in radians/s). */
float getLeanSpeed() const { return m_lean_speed; }
// ------------------------------------------------------------------------
/** Return show long a jump must last in order to play the jump
* animation. */
float getJumpAnimationTime() const { return m_jump_animation_time; }
// ------------------------------------------------------------------------
/** Returns true if wheels should have random rotation at start. */
bool hasRandomWheels() const { return m_has_rand_wheels; }
// ------------------------------------------------------------------------
/** Returns minimum time during which nitro is consumed when pressing nitro
* key, to prevent using nitro in very short bursts
*/
float getNitroMinConsumptionTime() const { return m_nitro_min_consumption; }
// ------------------------------------------------------------------------
/** Returns the bevel factor (!=0 indicates to use a bevelled box). */
const Vec3 &getBevelFactor() const { return m_bevel_factor; }

View File

@ -162,10 +162,8 @@ void MainLoop::run()
PROFILER_PUSH_CPU_MARKER("IrrDriver update", 0x00, 0x00, 0x7F);
irr_driver->update(dt);
PROFILER_POP_CPU_MARKER();
PROFILER_SYNC_FRAME();
}
PROFILER_SYNC_FRAME();
PROFILER_POP_CPU_MARKER();
} // while !m_exit

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -54,7 +54,6 @@ public:
virtual void reset();
virtual bool raceHasLaps(){ return false; }
virtual void moveKartAfterRescue(AbstractKart* kart);
virtual const std::string& getIdent() const;

View File

@ -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;

View File

@ -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
// ------------------------------------------------------------------------

View File

@ -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

View File

@ -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;
};

View File

@ -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()
{

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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. */

View File

@ -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

View File

@ -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

View File

@ -214,7 +214,7 @@ void AddonsScreen::loadList()
// Get the filter by rating.
GUIEngine::SpinnerWidget* w_filter_rating =
getWidget<GUIEngine::SpinnerWidget>("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<const Addon, REF> sorted_list;

View File

@ -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<ButtonWidget>("continue");
cancelbtn->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
World::getWorld()->getKart(0)->getControls().reset();
}
// ------------------------------------------------------------------------------------------------------

View File

@ -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);

View File

@ -77,44 +77,12 @@ void RaceSetupScreen::eventCallback(Widget* widget, const std::string& name, con
{
if (name == "difficulty")
{
RibbonWidget* w = dynamic_cast<RibbonWidget*>(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<DynamicRibbonWidget*>(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<RibbonWidget>("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<DynamicRibbonWidget>("gamemode");

View File

@ -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 */

View File

@ -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; i<m_all_physics_only_nodes.size(); i++)
{
convertTrackToBullet(m_all_physics_only_nodes[i]);
irr_driver->removeNode(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

View File

@ -174,8 +174,14 @@ private:
/** The base dir of all files of this track. */
std::string m_root;
std::vector<std::string> m_groups;
/** The list of all nodes. */
std::vector<scene::ISceneNode*> 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<scene::ISceneNode*> 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<scene::IMesh*> m_all_cached_meshes;

View File

@ -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

View File

@ -20,6 +20,7 @@
#ifndef HEADER_LOG_HPP
#define HEADER_LOG_HPP
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@ -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);

View File

@ -19,9 +19,11 @@
#include "utils/string_utils.hpp"
#include "utils/log.hpp"
#include "coreutil.h"
#include "math.h"
#include <math.h>
#include <algorithm>
#include <cstring>
#include <stdio.h>
@ -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;
}