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"> <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" <icon-button id="cancel" width="64" height="64" icon="gui/green_check.png"
I18N="Registration dialog" text="Close" label_location="none"/> I18N="Registration dialog" text="Close" label_location="none"/>
</buttonbar> </buttonbar>

View File

@ -2,7 +2,7 @@
<div x="2%" y="5%" width="96%" height="90%" layout="vertical-row" > <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"/> I18N="In the registration dialog' dialog" text="Registration Complete"/>
<spacer height="20" width="50"> <spacer height="20" width="50">
@ -12,7 +12,7 @@
<spacer height="20" width="50"> <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" <icon-button id="cancel" width="64" height="64" icon="gui/green_check.png"
I18N="Registration dialog" text="Close" label_location="none"/> I18N="Registration dialog" text="Close" label_location="none"/>
</buttonbar> </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" <camera distance="1.5" forward-up-angle="15"
backward-up-angle="30"/> 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', <!-- If a kart starts within the specified time after 'go',
it receives the corresponding bonus from 'boost'. Those it receives the corresponding bonus from 'boost'. Those
fields must have the same size, and must be sorted by fields must have the same size, and must be sorted by

View File

@ -43,14 +43,6 @@
#include "utils/time.hpp" #include "utils/time.hpp"
#include "utils/translation.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 /** Create a thread that handles all network functions independent of the
* main program. NetworkHttp supports only a single thread (i.e. it's not * 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; const int NO_TRUST_COUNT = 200;
static int no_trust = NO_TRUST_COUNT; 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 // Min and max info tracking, per mode, so user can check game vs menus
bool current_state = StateManager::get()->getGameState() bool current_state = StateManager::get()->getGameState()
== GUIEngine::GAME; == GUIEngine::GAME;
@ -1303,6 +1286,23 @@ void IrrDriver::displayFPS()
prev_state = current_state; 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 (min > fps && fps > 1) min = fps; // Start moments sometimes give useless 1
if (max < fps) max = fps; if (max < fps) max = fps;
if (low > kilotris) low = kilotris; 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, irr_driver->getSceneManager()->setAmbientLight(video::SColor(255, 10, 10, 10) );
120, 120) );
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() m_light = irr_driver->getSceneManager()
->addLightSceneNode(NULL, sun_pos, video::SColorf(1.0f,1.0f,1.0f), ->addLightSceneNode(NULL, spot_pos, video::SColorf(1.0f,1.0f,1.0f),
10000.0f /* radius */); 1600 /* radius */);
m_light->getLightData().DiffuseColor m_light->setLightType(video::ELT_SPOT);
= video::SColorf(0.5f, 0.5f, 0.5f, 0.5f); m_light->setRotation((core::vector3df(0, 10, 0) - spot_pos).getHorizontalAngle());
m_light->getLightData().SpecularColor m_light->updateAbsolutePosition();
= video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
m_rtt_main_node->setMaterialFlag(video::EMF_GOURAUD_SHADING , true); m_rtt_main_node->setMaterialFlag(video::EMF_GOURAUD_SHADING , true);
m_rtt_main_node->setMaterialFlag(video::EMF_LIGHTING, 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("mask", &m_mask );
node->get("water-splash", &m_water_splash ); node->get("water-splash", &m_water_splash );
node->get("jump", &m_is_jump_texture );
if (m_collision_reaction != NORMAL) if (m_collision_reaction != NORMAL)
{ {
@ -732,6 +733,7 @@ void Material::init(unsigned int index)
m_is_heightmap = false; m_is_heightmap = false;
m_alpha_to_coverage = false; m_alpha_to_coverage = false;
m_water_splash = false; m_water_splash = false;
m_is_jump_texture = false;
m_shaders.resize(SHADER_COUNT, NULL); 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 * surface is not a physical object), but the location of the water
* effect is on the surface. */ * effect is on the surface. */
bool m_surface; bool m_surface;
/** If the material is a zipper, i.e. gives a speed boost. */ /** If the material is a zipper, i.e. gives a speed boost. */
bool m_zipper; bool m_zipper;
/** If a kart is rescued when driving on this surface. */ /** If a kart is rescued when driving on this surface. */
bool m_drive_reset; 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 /** Speed of the 'main' wave in the water shader. Only used if
m_graphical_effect == WATER_SHADER */ m_graphical_effect == WATER_SHADER */
@ -321,6 +326,10 @@ public:
* the special falling camera. */ * the special falling camera. */
bool hasFallingEffect() const {return m_falling_effect; } 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. */ /** Returns the zipper parametersfor the current material. */
void getZipperParameter(float *zipper_max_speed_increase, void getZipperParameter(float *zipper_max_speed_increase,
float *zipper_duration, 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_RIGHT) action = PA_MENU_RIGHT;
else if (button == KEY_SPACE) action = PA_MENU_SELECT; else if (button == KEY_SPACE) action = PA_MENU_SELECT;
else if (button == KEY_RETURN) 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()) if (button == KEY_RETURN && GUIEngine::ModalDialog::isADialogActive())
{ {

View File

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

View File

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

View File

@ -317,6 +317,11 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual void setEnergy(float val) = 0; 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. */ /** Returns the current material the kart is on. */
virtual const Material *getMaterial() const = 0; 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_flying = false;
m_sky_particles_emitter= NULL; m_sky_particles_emitter= NULL;
m_stars_effect = NULL; m_stars_effect = NULL;
m_timeFlying = 0; m_jump_time = 0;
m_isTimeFlying = false; m_is_jumping = false;
m_hitGround = NULL; m_min_nitro_time = 0.0f;
m_view_blocked_by_plunger = 0; m_view_blocked_by_plunger = 0;
m_has_caught_nolok_bubblegum = false; m_has_caught_nolok_bubblegum = false;
@ -295,6 +295,8 @@ void Kart::reset()
if(m_body) if(m_body)
World::getWorld()->getPhysics()->addKart(this); World::getWorld()->getPhysics()->addKart(this);
m_min_nitro_time = 0.0f;
// Reset star effect in case that it is currently being shown. // Reset star effect in case that it is currently being shown.
m_stars_effect->reset(); m_stars_effect->reset();
m_max_speed->reset(); m_max_speed->reset();
@ -339,6 +341,8 @@ void Kart::reset()
m_bubblegum_time = 0.0f; m_bubblegum_time = 0.0f;
m_bubblegum_torque = 0.0f; m_bubblegum_torque = 0.0f;
m_has_caught_nolok_bubblegum = false; m_has_caught_nolok_bubblegum = false;
m_is_jumping = false;
// In case that the kart was in the air, in which case its // In case that the kart was in the air, in which case its
// linear damping is 0 // linear damping is 0
m_body->setDamping(m_kart_properties->getChassisLinearDamping(), m_body->setDamping(m_kart_properties->getChassisLinearDamping(),
@ -1198,17 +1202,39 @@ void Kart::update(float dt)
// values for the raycasts). // values for the raycasts).
if (!isOnGround()) if (!isOnGround())
{ {
m_timeFlying+=dt; const Material *m = getMaterial();
m_isTimeFlying = true; 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;
} }
else if (m_is_jumping)
if(isOnGround() && m_isTimeFlying)
{ {
m_isTimeFlying = false; // Kart touched ground again
m_hitGround = new Explosion(getXYZ(), "jump", m_is_jumping = false;
"jump_explosion.xml"); HitEffect *effect = new Explosion(getXYZ(), "jump",
projectile_manager->addHitEffect(m_hitGround); "jump_explosion.xml");
m_timeFlying = 0; projectile_manager->addHitEffect(effect);
m_kart_model->setAnimation(KartModel::AF_DEFAULT);
m_jump_time = 0;
} }
if( (!isOnGround() || emergency) && m_shadow_enabled) if( (!isOnGround() || emergency) && m_shadow_enabled)
@ -1508,18 +1534,40 @@ void Kart::handleZipper(const Material *material, bool play_sound)
*/ */
void Kart::updateNitro(float dt) 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(); m_collected_energy -= dt * m_kart_properties->getNitroConsumption();
if(m_collected_energy<0) if (m_collected_energy < 0)
{ {
m_collected_energy = 0; m_collected_energy = 0;
return; return;
} }
m_max_speed->increaseMaxSpeed(MaxSpeed::MS_INCREASE_NITRO,
m_kart_properties->getNitroMaxSpeedIncrease(), if (increase_speed)
m_kart_properties->getNitroEngineForce(), {
m_kart_properties->getNitroDuration(), m_max_speed->increaseMaxSpeed(MaxSpeed::MS_INCREASE_NITRO,
m_kart_properties->getNitroFadeOutTime() ); m_kart_properties->getNitroMaxSpeedIncrease(),
m_kart_properties->getNitroEngineForce(),
m_kart_properties->getNitroDuration(),
m_kart_properties->getNitroFadeOutTime() );
}
} // updateNitro } // updateNitro
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -2254,7 +2302,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
y += m_skidding->getGraphicalJumpOffset(); y += m_skidding->getGraphicalJumpOffset();
center_shift.setY(y); 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 // fabs(speed) is important, otherwise the negative number will
// become a huge unsigned number in the particle scene node! // become a huge unsigned number in the particle scene node!

View File

@ -41,6 +41,7 @@ class Attachment;
class Controller; class Controller;
class Item; class Item;
class AbstractKartAnimation; class AbstractKartAnimation;
class HitEffect;
class KartGFX; class KartGFX;
class MaxSpeed; class MaxSpeed;
class ParticleEmitter; class ParticleEmitter;
@ -51,7 +52,6 @@ class Skidding;
class SkidMarks; class SkidMarks;
class SlipStream; class SlipStream;
class Stars; class Stars;
class HitEffect;
/** The main kart class. All type of karts are of this object, but with /** 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 * different controllers. The controllers are what turn a kart into a
@ -149,14 +149,11 @@ private:
// Graphical effects // Graphical effects
// ----------------- // -----------------
/** The time where a kart is flying */ /** Time a kart is jumping. */
float m_timeFlying; float m_jump_time;
/** For the effect when the kart touch the ground */
HitEffect *m_hitGround;
/** Is time flying activated */ /** Is time flying activated */
bool m_isTimeFlying; bool m_is_jumping;
/** The shadow of a kart. */ /** The shadow of a kart. */
Shadow *m_shadow; Shadow *m_shadow;
@ -210,6 +207,9 @@ private:
SFXBase *m_skid_sound; SFXBase *m_skid_sound;
SFXBase *m_goo_sound; SFXBase *m_goo_sound;
float m_time_last_crash; float m_time_last_crash;
/** To prevent using nitro in too short bursts */
float m_min_nitro_time;
void updatePhysics(float dt); void updatePhysics(float dt);
void handleMaterialSFX(const Material *material); void handleMaterialSFX(const Material *material);
@ -403,6 +403,11 @@ public:
/** Sets the energy the kart has collected. */ /** Sets the energy the kart has collected. */
virtual void setEnergy(float val) { m_collected_energy = val; } 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. */ /** Returns if the kart is currently being squashed. */
virtual bool isSquashed() const { return m_squash_time >0; } 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("end-losing", &m_animation_frame[AF_LOSE_END] );
animation_node->get("start-explosion",&m_animation_frame[AF_LOSE_START]); 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("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 ); 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-right", 2);
loadWheelInfo(*wheels_node, "rear-left", 3); 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); 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 // 'type' is the start frame of the animation, type + 1 the frame
// to begin the loop with, type + 2 to end the frame with // to begin the loop with, type + 2 to end the frame with
AnimationFrameType end = (AnimationFrameType)(type+2); 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->setAnimationSpeed(m_animation_speed);
m_animated_node->setFrameLoop(m_animation_frame[type], m_animated_node->setFrameLoop(m_animation_frame[type],
m_animation_frame[end] ); m_animation_frame[end] );
@ -613,10 +610,16 @@ void KartModel::OnAnimationEnd(scene::IAnimatedMeshSceneNode *node)
if(m_animation_frame[start]==-1) if(m_animation_frame[start]==-1)
start = m_current_animation; start = m_current_animation;
AnimationFrameType end = (AnimationFrameType)(m_current_animation+2); AnimationFrameType end = (AnimationFrameType)(m_current_animation+2);
m_animated_node->setAnimationSpeed(m_animation_speed);
m_animated_node->setFrameLoop(m_animation_frame[start], // Switch to loop mode if the current animation has a loop defined
m_animation_frame[end] ); // (else just disable the callback, and the last frame will be shown).
m_animated_node->setLoopMode(true); 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); m_animated_node->setAnimationEndCallback(NULL);
} // OnAnimationEnd } // OnAnimationEnd

View File

@ -60,6 +60,9 @@ public:
AF_LOSE_END, // End losing animation AF_LOSE_END, // End losing animation
AF_BEGIN_EXPLOSION, // Begin explosion animation AF_BEGIN_EXPLOSION, // Begin explosion animation
AF_END_EXPLOSION, // End 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_START, // Begin of win animation
AF_WIN_LOOP_START, // Begin of win loop animation AF_WIN_LOOP_START, // Begin of win loop animation
AF_WIN_END, // End of win 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_swatter_distance2 = m_swatter_duration = m_squash_slowdown =
m_squash_duration = m_downward_impulse_factor = m_squash_duration = m_downward_impulse_factor =
m_bubblegum_fade_in_time = m_bubblegum_speed_fraction = 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_engine_power.resize(RaceManager::DIFFICULTY_COUNT, UNDEFINED);
m_max_speed.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_engine_sfx_type = "engine_small";
m_kart_model = NULL; m_kart_model = NULL;
m_has_rand_wheels = false; m_has_rand_wheels = false;
m_nitro_min_consumption = 1.0f;
// The default constructor for stk_config uses filename="" // The default constructor for stk_config uses filename=""
if (filename != "") if (filename != "")
{ {
@ -312,6 +314,7 @@ void KartProperties::getAllData(const XMLNode * root)
nitro_node->get("duration", &m_nitro_duration ); nitro_node->get("duration", &m_nitro_duration );
nitro_node->get("fade-out-time", &m_nitro_fade_out_time ); nitro_node->get("fade-out-time", &m_nitro_fade_out_time );
nitro_node->get("max", &m_nitro_max ); 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")) if(const XMLNode *bubble_node = root->getNode("bubblegum"))
@ -519,6 +522,11 @@ void KartProperties::getAllData(const XMLNode * root)
m_lean_speed *= DEGREE_TO_RAD; 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")) if(const XMLNode *camera_node= root->getNode("camera"))
{ {
camera_node->get("distance", &m_camera_distance); camera_node->get("distance", &m_camera_distance);

View File

@ -176,6 +176,11 @@ private:
/** Vertical offset after rescue. */ /** Vertical offset after rescue. */
float m_rescue_vert_offset; 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. */ /** Filename of the wheel models. */
std::string m_wheel_filename[4]; std::string m_wheel_filename[4];
/** Radius of the graphical wheels. */ /** Radius of the graphical wheels. */
@ -243,6 +248,9 @@ private:
* (in radians/second). */ * (in radians/second). */
float m_lean_speed; 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. */ /** Engine sound effect. */
std::string m_engine_sfx_type; std::string m_engine_sfx_type;
@ -844,9 +852,17 @@ public:
/** The speed with which a kart should lean (in radians/s). */ /** The speed with which a kart should lean (in radians/s). */
float getLeanSpeed() const { return m_lean_speed; } 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. */ /** Returns true if wheels should have random rotation at start. */
bool hasRandomWheels() const { return m_has_rand_wheels; } 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). */ /** Returns the bevel factor (!=0 indicates to use a bevelled box). */
const Vec3 &getBevelFactor() const { return m_bevel_factor; } 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); PROFILER_PUSH_CPU_MARKER("IrrDriver update", 0x00, 0x00, 0x7F);
irr_driver->update(dt); irr_driver->update(dt);
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
PROFILER_SYNC_FRAME();
} }
PROFILER_SYNC_FRAME();
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
} // while !m_exit } // while !m_exit

View File

@ -416,37 +416,11 @@ bool CutsceneWorld::isRaceOver()
return m_time > m_duration; return m_time > m_duration;
} // isRaceOver } // 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() void CutsceneWorld::createRaceGUI()
{ {
m_race_gui = new CutsceneGUI(); m_race_gui = new CutsceneGUI();
} } // createRaceGUI

View File

@ -68,17 +68,6 @@ public:
// clock events // clock events
virtual bool isRaceOver() OVERRIDE; 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; virtual const std::string& getIdent() const OVERRIDE;
@ -88,8 +77,35 @@ public:
virtual void enterRaceOverState() OVERRIDE; 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(); } 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(); } virtual void escapePressed() OVERRIDE { abortCutscene(); }
}; // CutsceneWorld }; // CutsceneWorld

View File

@ -206,15 +206,3 @@ void EasterEggHunt::getKartsDisplayInfo(
} }
} // getKartDisplayInfo } // 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 void reset();
virtual bool raceHasLaps(){ return false; } virtual bool raceHasLaps(){ return false; }
virtual void moveKartAfterRescue(AbstractKart* kart);
virtual const std::string& getIdent() const; virtual const std::string& getIdent() const;

View File

@ -89,7 +89,7 @@ void LinearWorld::reset()
for(unsigned int i=0; i<kart_amount; i++) for(unsigned int i=0; i<kart_amount; i++)
{ {
m_kart_info[i].reset(); 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 } // next kart
// At the moment the last kart would be the one that is furthest away // 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 // rescued or eliminated
if(kart->getKartAnimation()) continue; 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 kart_info.m_overall_distance = kart_info.m_race_lap
* m_track->getTrackLength() * m_track->getTrackLength()
+ getDistanceDownTrackForKart(kart->getWorldKartId()); + getDistanceDownTrackForKart(kart->getWorldKartId());
@ -376,7 +376,7 @@ int LinearWorld::getSectorForKart(const AbstractKart *kart) const
{ {
if(kart->getWorldKartId()>=m_kart_info.size()) if(kart->getWorldKartId()>=m_kart_info.size())
return QuadGraph::UNKNOWN_SECTOR; return QuadGraph::UNKNOWN_SECTOR;
return m_kart_info[kart->getWorldKartId()].getSector() return m_kart_info[kart->getWorldKartId()].getTrackSector()
->getCurrentGraphNode(); ->getCurrentGraphNode();
} // getSectorForKart } // getSectorForKart
@ -388,7 +388,7 @@ int LinearWorld::getSectorForKart(const AbstractKart *kart) const
float LinearWorld::getDistanceDownTrackForKart(const int kart_id) const float LinearWorld::getDistanceDownTrackForKart(const int kart_id) const
{ {
assert(kart_id < (int)m_kart_info.size()); 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 } // getDistanceDownTrackForKart
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -399,7 +399,7 @@ float LinearWorld::getDistanceDownTrackForKart(const int kart_id) const
float LinearWorld::getDistanceToCenterForKart(const int kart_id) const float LinearWorld::getDistanceToCenterForKart(const int kart_id) const
{ {
assert(kart_id < (int)m_kart_info.size()); 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 } // getDistanceToCenterForKart
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -605,58 +605,37 @@ float LinearWorld::estimateFinishTimeForKart(AbstractKart* kart)
return est_time; return est_time;
} // estimateFinishTimeForKart } // 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()]; KartInfo& info = m_kart_info[kart->getWorldKartId()];
info.getSector()->rescue(); info.getTrackSector()->rescue();
// Setting XYZ for the kart is important since otherwise the kart // Setting XYZ for the kart is important since otherwise the kart
// will not detect the right material again when doing the next // will not detect the right material again when doing the next
// raycast to detect where it is driving on (--> potential rescue loop) // raycast to detect where it is driving on (--> potential rescue loop)
int sector = info.getSector()->getCurrentGraphNode(); return info.getTrackSector()->getCurrentGraphNode();
kart->setXYZ( QuadGraph::get()->getQuadOfNode(sector).getCenter()); } // getRescuePositionIndex
btQuaternion heading(btVector3(0.0f, 1.0f, 0.0f), // ------------------------------------------------------------------------
m_track->getAngle(sector) ); btTransform LinearWorld::getRescueTransform(unsigned int index) const
kart->setRotation(heading); {
// A certain epsilon is added here to the Z coordinate, in case const Vec3 &xyz = QuadGraph::get()->getQuadOfNode(index).getCenter();
// 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 pos; btTransform pos;
pos.setOrigin(xyz+btVector3(0, kart->getKartHeight() + epsilon,0)); pos.setOrigin(xyz);
pos.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f), pos.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f),
m_track->getAngle(sector))); m_track->getAngle(index)));
return pos;
kart->getBody()->setCenterOfMassTransform(pos); } // getRescueTransform
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
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Find the position (rank) of every kart. ATM it uses a stable O(n^2) /** 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) void LinearWorld::checkForWrongDirection(unsigned int i)
{ {
if(!m_karts[i]->getController()->isPlayerController()) return; 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; m_karts[i]->getKartAnimation()) return;
const AbstractKart *kart=m_karts[i]; const AbstractKart *kart=m_karts[i];
// If the kart can go in more than one directions from the current track // 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 // 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. // 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) if(QuadGraph::get()->getNumberOfSuccessors(sector)>1)
return; return;

View File

@ -79,7 +79,7 @@ private:
float m_overall_distance; float m_overall_distance;
/** Stores the current graph node and track coordinates etc. */ /** Stores the current graph node and track coordinates etc. */
TrackSector m_current_sector; TrackSector m_track_sector;
/** Initialises all fields. */ /** Initialises all fields. */
KartInfo() { reset(); } KartInfo() { reset(); }
@ -92,14 +92,14 @@ private:
m_time_at_last_lap = 99999.9f; m_time_at_last_lap = 99999.9f;
m_estimated_finish = -1.0f; m_estimated_finish = -1.0f;
m_overall_distance = 0.0f; m_overall_distance = 0.0f;
m_current_sector.reset(); m_track_sector.reset();
} // reset } // reset
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Returns a pointer to the current node object. */ /** 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. */ /** 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( virtual void getKartsDisplayInfo(
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE; 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 reset() OVERRIDE;
virtual void newLap(unsigned int kart_index) OVERRIDE; virtual void newLap(unsigned int kart_index) OVERRIDE;
@ -151,7 +154,7 @@ public:
* \param kart_index Index of the kart. */ * \param kart_index Index of the kart. */
bool isOnRoad(unsigned int kart_index) const bool isOnRoad(unsigned int kart_index) const
{ {
return m_kart_info[kart_index].getSector()->isOnRoad(); return m_kart_info[kart_index].getTrackSector()->isOnRoad();
} // isOnRoad } // isOnRoad
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -168,7 +171,7 @@ public:
* \param kart_index World index of the kart. */ * \param kart_index World index of the kart. */
TrackSector& getTrackSector(unsigned int kart_index) 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 } // getTrackSector
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -34,9 +34,9 @@
#include "tracks/track.hpp" #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; m_stop_music_when_dialog_open = false;
} // Overworld } // Overworld
@ -115,7 +115,7 @@ void OverWorld::update(float dt)
music_manager->getCurrentMusic()->startMusic(); music_manager->getCurrentMusic()->startMusic();
m_karts[0]->startEngineSFX(); m_karts[0]->startEngineSFX();
} }
LinearWorld::update(dt); WorldWithRank::update(dt);
const unsigned int kart_amount = m_karts.size(); const unsigned int kart_amount = m_karts.size();
// isn't it cool, on the overworld nitro is free! // isn't it cool, on the overworld nitro is free!
@ -136,6 +136,15 @@ void OverWorld::update(float dt)
} }
} // update } // 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 /** Override the base class method to change behavior. We don't want wrong
* direction messages in the overworld since there is no direction there. * direction messages in the overworld since there is no direction there.
@ -191,96 +200,6 @@ void OverWorld::onFirePressed(Controller* who)
} // end for } // end for
} // onFirePressed } // 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 /** 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 * 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) 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); AbstractKart* kart = getKart(0);
const btTransform& s = getClosestStartPoint(challenge->m_position.X, kart->setXYZ(challenge->m_position);
challenge->m_position.Z);
const Vec3 &xyz = s.getOrigin(); unsigned int index = getRescuePositionIndex(kart);
float angle = atan2(challenge->m_position.X - xyz[0], btTransform s = getRescueTransform(index);
challenge->m_position.Z - xyz[2]); const btVector3 &xyz = s.getOrigin();
kart->setXYZ(xyz); float angle = atan2(challenge->m_position.X - xyz[0],
moveKartAfterRescue(kart, angle); challenge->m_position.Z - xyz[2]);
s.setRotation( btQuaternion(btVector3(0.0f, 1.0f, 0.0f), angle) );
moveKartTo(kart, s);
return; return;
} }
} // onMouseClick } // onMouseClick

View File

@ -20,7 +20,7 @@
#include <vector> #include <vector>
#include "modes/linear_world.hpp" #include "modes/world_with_rank.hpp"
#include "utils/aligned_array.hpp" #include "utils/aligned_array.hpp"
#include "LinearMath/btTransform.h" #include "LinearMath/btTransform.h"
@ -32,7 +32,7 @@
* linear. * linear.
* \ingroup modes * \ingroup modes
*/ */
class OverWorld : public LinearWorld class OverWorld : public WorldWithRank
{ {
protected: protected:
@ -41,10 +41,6 @@ protected:
bool m_return_to_garage; bool m_return_to_garage;
void moveKartAfterRescue(AbstractKart* kart, float angle);
btTransform getClosestStartPoint(float currentKart_x, float currentKart_z);
public: public:
OverWorld(); OverWorld();
virtual ~OverWorld(); virtual ~OverWorld();
@ -52,7 +48,8 @@ public:
static void enterOverWorld(); static void enterOverWorld();
virtual void update(float delta) OVERRIDE; virtual void update(float delta) OVERRIDE;
virtual void getKartsDisplayInfo(
std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns if this race mode has laps. */ /** Returns if this race mode has laps. */
virtual bool raceHasLaps() OVERRIDE { return false; } virtual bool raceHasLaps() OVERRIDE { return false; }
@ -77,8 +74,6 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void scheduleSelectKart() { m_return_to_garage = true; } void scheduleSelectKart() { m_return_to_garage = true; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual void moveKartAfterRescue(AbstractKart* kart) OVERRIDE;
// ------------------------------------------------------------------------
virtual void onMouseClick(int x, int y) OVERRIDE; virtual void onMouseClick(int x, int y) OVERRIDE;
}; };

View File

@ -191,88 +191,7 @@ void SoccerWorld::getKartsDisplayInfo(
*/ */
} // 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 */ /** Set position and team for the karts */
void SoccerWorld::initKartList() void SoccerWorld::initKartList()
{ {

View File

@ -64,7 +64,6 @@ public:
virtual void getKartsDisplayInfo( virtual void getKartsDisplayInfo(
std::vector<RaceGUIBase::KartIconDisplayInfo> *info); std::vector<RaceGUIBase::KartIconDisplayInfo> *info);
virtual bool raceHasLaps(){ return false; } virtual bool raceHasLaps(){ return false; }
virtual void moveKartAfterRescue(AbstractKart* kart);
virtual const std::string& getIdent() const; virtual const std::string& getIdent() const;

View File

@ -1,3 +1,5 @@
// SuperTuxKart - a fun racing game with go-kart // SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006 SuperTuxKart-Team // Copyright (C) 2006 SuperTuxKart-Team
// //
@ -477,83 +479,52 @@ void ThreeStrikesBattle::getKartsDisplayInfo(
} // getKartsDisplayInfo } // getKartsDisplayInfo
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Moves a kart to its rescue position. /** Determines the rescue position for a kart. The rescue position is the
* \param kart The kart that was rescued. * 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 const int start_spots_amount = getTrack()->getNumberOfStartPositions();
World *world = World::getWorld();
const int start_spots_amount = world->getTrack()->getNumberOfStartPositions();
assert(start_spots_amount > 0); assert(start_spots_amount > 0);
float largest_accumulated_distance_found = -1; float largest_accumulated_distance_found = -1;
int furthest_id_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++) for(int n=0; n<start_spots_amount; n++)
{ {
// no need for the overhead to compute exact distance with sqrt(), const btTransform &s = getTrack()->getStartTransform(n);
// so using the 'manhattan' heuristic which will do fine enough.
const btTransform &s = world->getTrack()->getStartTransform(n);
const Vec3 &v=s.getOrigin(); const Vec3 &v=s.getOrigin();
float accumulatedDistance = .0f; float accumulated_distance = .0f;
bool spawnPointClear = true; bool spawn_point_clear = true;
for(unsigned int k=0; k<getCurrentNumKarts(); k++) for(unsigned int k=0; k<getCurrentNumKarts(); k++)
{ {
const AbstractKart *currentKart = World::getWorld()->getKart(k); if(kart->getWorldKartId()==k) continue;
const float currentKart_x = currentKart->getXYZ().getX(); float abs_distance2 = (getKart(k)->getXYZ()-v).length2_2d();
const float currentKartk_z = currentKart->getXYZ().getZ(); const float CLEAR_SPAWN_RANGE2 = 5*5;
if( abs_distance2 < CLEAR_SPAWN_RANGE2)
if(kart_x!=currentKart_x && kart_z !=currentKartk_z)
{ {
float absDistance = fabs(currentKart_x - v.getX()) + spawn_point_clear = false;
fabs(currentKartk_z - v.getZ()); break;
if(absDistance < CLEAR_SPAWN_RANGE)
{
spawnPointClear = false;
break;
}
accumulatedDistance += absDistance;
} }
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; furthest_id_found = n;
largest_accumulated_distance_found = accumulatedDistance; largest_accumulated_distance_found = accumulated_distance;
} }
} }
assert(furthest_id_found != -1); assert(furthest_id_found != -1);
const btTransform &s = world->getTrack()->getStartTransform(furthest_id_found); return furthest_id_found;
const Vec3 &xyz = s.getOrigin(); } // getRescuePositionIndex
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

View File

@ -16,8 +16,8 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef THREE_STRIKES_HPP #ifndef THREE_STRIKES_BATTLE_HPP
#define THREE_STRIKES_HPP #define THREE_STRIKES_BATTLE_HPP
#include "modes/world_with_rank.hpp" #include "modes/world_with_rank.hpp"
@ -28,8 +28,6 @@
#include <string> #include <string>
#define CLEAR_SPAWN_RANGE 5
class PhysicalObject; class PhysicalObject;
/** /**
@ -99,7 +97,7 @@ public:
virtual void getKartsDisplayInfo( virtual void getKartsDisplayInfo(
std::vector<RaceGUIBase::KartIconDisplayInfo> *info); std::vector<RaceGUIBase::KartIconDisplayInfo> *info);
virtual bool raceHasLaps(){ return false; } virtual bool raceHasLaps(){ return false; }
virtual void moveKartAfterRescue(AbstractKart* kart); virtual unsigned int getRescuePositionIndex(AbstractKart *kart);
virtual const std::string& getIdent() const; virtual const std::string& getIdent() const;

View File

@ -7,88 +7,4 @@
TutorialWorld::TutorialWorld() TutorialWorld::TutorialWorld()
{ {
m_stop_music_when_dialog_open = false; m_stop_music_when_dialog_open = false;
} } // TutorialWorld
// -----------------------------------------------------------------------------
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

View File

@ -6,13 +6,32 @@
class TutorialWorld : public StandardRace class TutorialWorld : public StandardRace
{ {
private:
btTransform getClosestStartPoint(float currentKart_x, float currentKart_z);
public: public:
TutorialWorld(); 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 #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 * 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 * will be estimated), highscore is updated, and the race result gui
* is being displayed. * 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 /** Constructor. Note that in the constructor it is not possible to call any
* functions that use World::getWorld(), since this is only defined * functions that use World::getWorld(), since this is only defined
@ -320,7 +335,7 @@ Controller* World::loadAIController(AbstractKart *kart)
controller = new SkiddingAI(kart); controller = new SkiddingAI(kart);
break; break;
default: default:
fprintf(stderr, "Warning: Unknown robot, using default.\n"); Log::warn("World", "Unknown AI, using default.");
controller = new SkiddingAI(kart); controller = new SkiddingAI(kart);
break; break;
} }
@ -471,65 +486,31 @@ void World::resetAllKarts()
// If track checking is requested, check all rescue positions if // If track checking is requested, check all rescue positions if
// they are heigh enough. // they are heigh enough.
if(race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES && if(UserConfigParams::m_track_debug)
UserConfigParams::m_track_debug)
{ {
Vec3 eps = Vec3(0,1.5f*m_karts[0]->getKartHeight(),0); // Loop over all karts, in case that some karts are dfferent
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
for(unsigned int kart_id=0; kart_id<m_karts.size(); kart_id++) 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. // Reset the karts back to the original start position.
// This call is a bit of an overkill, but setting the correct // This call is a bit of an overkill, but setting the correct
// transforms, positions, motion state is a bit of a hassle. // transforms, positions, motion state is a bit of a hassle.
m_karts[kart_id]->reset(); m_karts[kart_id]->reset();
} } // for kart_id<m_karts.size()
} // if m_track_debug } // if m_track_debug
m_schedule_pause = false; m_schedule_pause = false;
m_schedule_unpause = false; m_schedule_unpause = false;
@ -546,13 +527,12 @@ void World::resetAllKarts()
if (!kart_over_ground) if (!kart_over_ground)
{ {
fprintf(stderr, Log::error("World",
"ERROR: no valid starting position for kart %d " "No valid starting position for kart %d on track %s.",
"on track %s.\n", (int)(i-m_karts.begin()), m_track->getIdent().c_str());
(int)(i-m_karts.begin()), m_track->getIdent().c_str());
if (UserConfigParams::m_artist_debug_mode) if (UserConfigParams::m_artist_debug_mode)
{ {
fprintf(stderr, "Activating fly mode.\n"); Log::warn("World", "Activating fly mode.");
(*i)->flyUp(); (*i)->flyUp();
continue; continue;
} }
@ -598,14 +578,14 @@ void World::resetAllKarts()
&normal); &normal);
if(!material) if(!material)
{ {
fprintf(stderr, Log::error("World",
"ERROR: no valid starting position for " "No valid starting position for kart %d "
"kart %d on track %s.\n", "on track %s.",
(int)(i-m_karts.begin()), (int)(i-m_karts.begin()),
m_track->getIdent().c_str()); m_track->getIdent().c_str());
if (UserConfigParams::m_artist_debug_mode) if (UserConfigParams::m_artist_debug_mode)
{ {
fprintf(stderr, "Activating fly mode.\n"); Log::warn("World", "Activating fly mode.");
(*i)->flyUp(); (*i)->flyUp();
continue; continue;
} }
@ -637,6 +617,44 @@ void World::resetAllKarts()
} }
} // 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) void World::schedulePause(Phase phase)
{ {
@ -730,13 +748,15 @@ void World::updateWorld(float dt)
InputDevice* device = input_manager->getDeviceList()->getKeyboard(0); InputDevice* device = input_manager->getDeviceList()->getKeyboard(0);
// Create player and associate player with keyboard // Create player and associate player with keyboard
StateManager::get()->createActivePlayer(unlock_manager->getCurrentPlayer(), StateManager::get()
device); ->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", Log::warn("World",
UserConfigParams::m_default_kart.c_str()); "Cannot find kart '%s', will revert to default.",
UserConfigParams::m_default_kart.c_str());
UserConfigParams::m_default_kart.revertToDefaults(); UserConfigParams::m_default_kart.revertToDefaults();
} }
race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart); 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 // the kart location data is wrong
#ifdef DEBUG #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++ ) for (unsigned int i=0; i<m_karts.size(); i++ )
{ {
fprintf(stderr, "i=%d position %d\n",i, Log::error("World", "i=%d position %d.",i,
m_karts[i]->getPosition()); m_karts[i]->getPosition());
} }
#endif #endif
continue; continue;

View File

@ -33,6 +33,8 @@
#include "states_screens/state_manager.hpp" #include "states_screens/state_manager.hpp"
#include "utils/random_generator.hpp" #include "utils/random_generator.hpp"
#include "LinearMath/btTransform.h"
class AbstractKart; class AbstractKart;
class btRigidBody; class btRigidBody;
class Controller; class Controller;
@ -156,6 +158,7 @@ protected:
virtual void update(float dt); virtual void update(float dt);
virtual void createRaceGUI(); virtual void createRaceGUI();
void updateTrack(float dt); void updateTrack(float dt);
void moveKartTo(AbstractKart* kart, const btTransform &t);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Used for AI karts that are still racing when all player kart finished. /** 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 * 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 /** Each game mode should have a unique identifier. Override
* this method in child classes to provide it. */ * this method in child classes to provide it. */
virtual const std::string& virtual const std::string& getIdent() const = 0;
getIdent() const = 0;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Since each mode will have a different way of deciding where a rescued /** Returns the number of rescue positions on a given track and game
* kart is dropped, this method will be called and each mode can implement * mode. */
* it. */ virtual unsigned int getNumberOfRescuePositions() const OVERRIDE = 0;
virtual void moveKartAfterRescue(AbstractKart* kart) = 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 /** Called when it is needed to know whether this kind of race involves
* counting laps. */ * counting laps. */

View File

@ -18,7 +18,9 @@
#include "modes/world_with_rank.hpp" #include "modes/world_with_rank.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "karts/kart_properties.hpp"
#include "race/history.hpp" #include "race/history.hpp"
#include "tracks/track.hpp"
#include <iostream> #include <iostream>
@ -120,3 +122,53 @@ void WorldWithRank::endSetKartPositions()
} // 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 * 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. * 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) * 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 * \ingroup modes
*/ */
class WorldWithRank : public World class WorldWithRank : public World
@ -51,6 +54,8 @@ protected:
bool m_position_setting_initialised; bool m_position_setting_initialised;
#endif #endif
unsigned int getClosestStartPoint(AbstractKart *kart);
public: public:
WorldWithRank() : World() {} WorldWithRank() : World() {}
/** call just after instanciating. can't be moved to the contructor as child /** call just after instanciating. can't be moved to the contructor as child
@ -64,8 +69,13 @@ public:
bool setKartPosition(unsigned int kart_id, bool setKartPosition(unsigned int kart_id,
unsigned int position); unsigned int position);
void endSetKartPositions(); void endSetKartPositions();
AbstractKart* getKartAtPosition(unsigned int p) const; 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 }; // WorldWithRank
#endif #endif

View File

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

View File

@ -21,6 +21,7 @@
#include "guiengine/screen.hpp" #include "guiengine/screen.hpp"
#include "guiengine/widgets/button_widget.hpp" #include "guiengine/widgets/button_widget.hpp"
#include "guiengine/widgets/label_widget.hpp" #include "guiengine/widgets/label_widget.hpp"
#include "karts/abstract_kart.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "states_screens/state_manager.hpp" #include "states_screens/state_manager.hpp"
#include "utils/translation.hpp" #include "utils/translation.hpp"
@ -48,6 +49,8 @@ TutorialMessageDialog::TutorialMessageDialog(irr::core::stringw msg, bool stopGa
ButtonWidget* cancelbtn = getWidget<ButtonWidget>("continue"); ButtonWidget* cancelbtn = getWidget<ButtonWidget>("continue");
cancelbtn->setFocusForPlayer(PLAYER_ID_GAME_MASTER); 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; video::SMaterial m;
if(kart->getControls().m_nitro) if(kart->getControls().m_nitro || kart->isOnMinNitroTime())
m.setTexture(0, m_gauge_full_bright); m.setTexture(0, m_gauge_full_bright);
else else
m.setTexture(0, m_gauge_full); 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") if (name == "difficulty")
{ {
RibbonWidget* w = dynamic_cast<RibbonWidget*>(widget); assignDifficulty();
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);
}
}
} }
else if (name == "gamemode") else if (name == "gamemode")
{ {
assignDifficulty();
DynamicRibbonWidget* w = dynamic_cast<DynamicRibbonWidget*>(widget); DynamicRibbonWidget* w = dynamic_cast<DynamicRibbonWidget*>(widget);
const std::string& selectedMode = w->getSelectionIDString(PLAYER_ID_GAME_MASTER); 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() void RaceSetupScreen::onGameModeChanged()
{ {
DynamicRibbonWidget* w2 = getWidget<DynamicRibbonWidget>("gamemode"); DynamicRibbonWidget* w2 = getWidget<DynamicRibbonWidget>("gamemode");

View File

@ -39,6 +39,8 @@ class RaceSetupScreen : public GUIEngine::Screen, public GUIEngine::ScreenSingle
void onGameModeChanged(); void onGameModeChanged();
void assignDifficulty();
public: public:
/** \brief implement callback from parent class GUIEngine::Screen */ /** \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_x_scale = 1.0f;
m_minimap_y_scale = 1.0f; m_minimap_y_scale = 1.0f;
m_all_nodes.clear(); m_all_nodes.clear();
m_all_physics_only_nodes.clear();
m_all_cached_meshes.clear(); m_all_cached_meshes.clear();
loadTrackInfo(); loadTrackInfo();
} // Track } // Track
@ -182,6 +183,7 @@ void Track::cleanup()
irr_driver->removeNode(m_all_nodes[i]); irr_driver->removeNode(m_all_nodes[i]);
} }
m_all_nodes.clear(); m_all_nodes.clear();
m_all_physics_only_nodes.clear();
m_all_emitters.clearAndDeleteAll(); m_all_emitters.clearAndDeleteAll();
@ -955,6 +957,8 @@ bool Track::loadMainTrack(const XMLNode &root)
model_name=""; model_name="";
n->get("model", &model_name); n->get("model", &model_name);
full_path = m_root+model_name; full_path = m_root+model_name;
std::string interaction;
n->get("interaction", &interaction);
// a special challenge orb object for overworld // a special challenge orb object for overworld
std::string challenge; std::string challenge;
@ -1035,7 +1039,6 @@ bool Track::loadMainTrack(const XMLNode &root)
scene_node->setPosition(xyz); scene_node->setPosition(xyz);
scene_node->setRotation(hpr); scene_node->setRotation(hpr);
scene_node->setScale(scale); scene_node->setScale(scale);
#ifdef DEBUG #ifdef DEBUG
std::string debug_name = model_name+" (static track-object)"; std::string debug_name = model_name+" (static track-object)";
scene_node->setName(debug_name.c_str()); scene_node->setName(debug_name.c_str());
@ -1117,7 +1120,10 @@ bool Track::loadMainTrack(const XMLNode &root)
} }
else 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]); 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) if (m_track_mesh == NULL)
{ {
Log::fatal("track", "m_track_mesh == NULL, cannot loadMainTrack\n"); Log::fatal("track", "m_track_mesh == NULL, cannot loadMainTrack\n");
@ -2068,17 +2084,17 @@ bool Track::findGround(AbstractKart *kart)
} }
btTransform t = kart->getBody()->getCenterOfMassTransform(); btTransform t = kart->getBody()->getCenterOfMassTransform();
// The computer offset is slightly too large, it should take // The computer offset is slightly too large, it should take
// the default suspension rest insteat of suspension rest (i.e. the // the default suspension rest insteat of suspension rest (i.e. the
// length of the suspension with the weight of the kart resting on // length of the suspension with the weight of the kart resting on
// it). On the other hand this initial bouncing looks nice imho // it). On the other hand this initial bouncing looks nice imho
// - so I'll leave it in for now. // - so I'll leave it in for now.
float offset = kart->getKartProperties()->getSuspensionRest() + float offset = kart->getKartProperties()->getSuspensionRest() +
kart->getKartProperties()->getWheelRadius(); kart->getKartProperties()->getWheelRadius();
t.setOrigin(hit_point+Vec3(0, offset, 0) ); t.setOrigin(hit_point+Vec3(0, offset, 0) );
kart->getBody()->setCenterOfMassTransform(t); kart->getBody()->setCenterOfMassTransform(t);
kart->setTrans(t); kart->setTrans(t);
return true; return true;
} // findGround } // findGround

View File

@ -174,8 +174,14 @@ private:
/** The base dir of all files of this track. */ /** The base dir of all files of this track. */
std::string m_root; std::string m_root;
std::vector<std::string> m_groups; std::vector<std::string> m_groups;
/** The list of all nodes. */
std::vector<scene::ISceneNode*> m_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 /** 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. */ * that those meshes are being cached by irrlicht, and need to be freed. */
std::vector<scene::IMesh*> m_all_cached_meshes; std::vector<scene::IMesh*> m_all_cached_meshes;

View File

@ -90,7 +90,7 @@ public:
TrackObjectPresentation* presentation, TrackObjectPresentation* presentation,
bool is_dynamic, bool is_dynamic,
const PhysicalObject::Settings* physicsSettings); const PhysicalObject::Settings* physicsSettings);
~TrackObject(); virtual ~TrackObject();
virtual void update(float dt); virtual void update(float dt);
virtual void reset(); virtual void reset();
/** To finish object constructions. Called after the track model /** To finish object constructions. Called after the track model

View File

@ -20,6 +20,7 @@
#ifndef HEADER_LOG_HPP #ifndef HEADER_LOG_HPP
#define HEADER_LOG_HPP #define HEADER_LOG_HPP
#include <assert.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -66,7 +67,9 @@ public:
static void printMessage(int level, const char *component, static void printMessage(int level, const char *component,
const char *format, VALIST va_list); 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) \ #define LOG(NAME, LEVEL) \
static void NAME(const char *component, const char *format, ...) \ static void NAME(const char *component, const char *format, ...) \
{ \ { \
@ -76,7 +79,11 @@ public:
printMessage(LEVEL, component, format, args); \ printMessage(LEVEL, component, format, args); \
va_end(args); \ va_end(args); \
\ \
if (LEVEL == LL_FATAL) exit(1); \ if (LEVEL == LL_FATAL) \
{ \
assert(false); \
exit(1); \
} \
} }
LOG(verbose, LL_VERBOSE); LOG(verbose, LL_VERBOSE);
LOG(debug, LL_DEBUG); LOG(debug, LL_DEBUG);

View File

@ -19,9 +19,11 @@
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
#include "utils/log.hpp"
#include "coreutil.h" #include "coreutil.h"
#include "math.h" #include <math.h>
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include <stdio.h> #include <stdio.h>
@ -191,14 +193,14 @@ namespace StringUtils
} }
catch (std::exception& e) catch (std::exception& e)
{ {
fprintf(stderr, Log::error("StringUtils",
"Fatal error in split(std::string) : %s @ line %i : %s\n", "Error in split(std::string) : %s @ line %i : %s.",
__FILE__, __LINE__, e.what()); __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++) 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 assert(false); // in debug mode, trigger debugger
@ -253,10 +255,9 @@ namespace StringUtils
catch (std::exception& e) catch (std::exception& e)
{ {
(void)e; // avoid warning about unused variable (void)e; // avoid warning about unused variable
fprintf(stderr, Log::fatal("StringUtils",
"Fatal error in split(stringw) : %s @ line %i : %s\n", "Fatal error in split(stringw) : %s @ line %i : '%s'.",
__FILE__, __LINE__, e.what()); __FILE__, __LINE__, e.what());
assert(false); // in dbug mode, trigger debugger
exit(1); exit(1);
} }
} // split } // split
@ -310,8 +311,9 @@ namespace StringUtils
catch (std::exception& e) catch (std::exception& e)
{ {
(void)e; // avoid warning about unused variable (void)e; // avoid warning about unused variable
fprintf(stderr, "Fatal error in splitPath : %s @ line %i\n", Log::fatal("StringUtils",
__FILE__, __LINE__); "Fatal error in splitPath : %s @ line %i: '%s'.",
__FILE__, __LINE__, path.c_str());
exit(1); exit(1);
} }
} // splitPath } // splitPath
@ -340,10 +342,10 @@ namespace StringUtils
{ {
if (insertValID >= all_vals.size()) if (insertValID >= all_vals.size())
{ {
fprintf(stderr, Log::warn("StringUtils",
"[StringUtils::insertValues] ERROR: " "insertValues: "
"Invalid number of arguments in '%s'\n", "Invalid number of arguments in '%s'.",
s.c_str()); s.c_str());
new_string += "??" + sv[i].substr(2); new_string += "??" + sv[i].substr(2);
} }
else else
@ -358,9 +360,9 @@ namespace StringUtils
const unsigned int index = sv[i][1] - '0'; const unsigned int index = sv[i][1] - '0';
if (index >= all_vals.size()) if (index >= all_vals.size())
{ {
fprintf(stderr,"[StringUtils::insertValues] ERROR:" Log::warn("StringUtils", "insertValues: "
" Invalid argument index in '%s' " " Invalid argument index in '%s' "
"for %i\n", s.c_str(), index); "for %i.", s.c_str(), index);
new_string += "??" + sv[i].substr(2); new_string += "??" + sv[i].substr(2);
} }
else else
@ -379,8 +381,9 @@ namespace StringUtils
catch (std::exception& e) catch (std::exception& e)
{ {
(void)e; // avoid warning about unused variable (void)e; // avoid warning about unused variable
fprintf(stderr, "Fatal error in insertValues(std::string) : %s @ " Log::fatal("StringUtils",
"line %i\n", __FILE__, __LINE__); "Fatal error in insertValues(std::string) : %s @ "
"line %i: '%s'", __FILE__, __LINE__, s.c_str());
exit(1); exit(1);
} }
} }
@ -411,10 +414,9 @@ namespace StringUtils
{ {
if (insertValID >= all_vals.size()) if (insertValID >= all_vals.size())
{ {
fprintf(stderr, Log::warn("StringUtils", "insertValues: "
"[StringUtils::insertValues] ERROR: " "Invalid number of arguments in '%s'\n",
"Invalid number of arguments in '%s'\n", irr::core::stringc(s.c_str()).c_str());
irr::core::stringc(s.c_str()).c_str());
new_string += "??"; new_string += "??";
new_string += sv[i].subString(2, sv[i].size()-2); new_string += sv[i].subString(2, sv[i].size()-2);
} }
@ -442,11 +444,10 @@ namespace StringUtils
- '0' + delta; - '0' + delta;
if (index >= all_vals.size()) if (index >= all_vals.size())
{ {
fprintf(stderr, Log::warn("StringUtils", "insertValues: "
"[StringUtils::insertValues] ERROR: " "Invalid argument ID in '%s' : %i\n",
"Invalid argument ID in '%s' : %i\n", irr::core::stringc(s.c_str()).c_str(),
irr::core::stringc(s.c_str()).c_str(), index);
index);
new_string += "??"; new_string += "??";
new_string += rest; new_string += rest;
} }
@ -466,9 +467,9 @@ namespace StringUtils
catch (std::exception& e) catch (std::exception& e)
{ {
(void)e; // avoid warning about unused variable (void)e; // avoid warning about unused variable
fprintf(stderr, Log::fatal("StringUtils",
"Fatal error in insertValues(stringw) : %s @ line %i\n", "Fatal error in insertValues(stringw) : %s @ line %i.",
__FILE__, __LINE__); __FILE__, __LINE__);
exit(1); exit(1);
} }
} }
@ -599,10 +600,9 @@ namespace StringUtils
} }
else else
{ {
fprintf(stderr, Log::warn("StringUtils", "non-numeric HTML "
"[StringUtils] WARNING: non-numeric HTML " "entity not supported in '%s'.",
"entity not supported in '%s'\n", input.c_str());
input.c_str());
} }
state = NORMAL; state = NORMAL;
} }