Merge branch 'master' into kart-properties
Conflicts: src/karts/kart.cpp
This commit is contained in:
commit
586724c855
@ -1088,16 +1088,29 @@ scene::IMeshSceneNode *IrrDriver::addOctTree(scene::IMesh *mesh)
|
||||
scene::IMeshSceneNode *IrrDriver::addSphere(float radius,
|
||||
const video::SColor &color)
|
||||
{
|
||||
scene::IMeshSceneNode *node = m_scene_manager->addSphereSceneNode(radius);
|
||||
node->setMaterialType(video::EMT_SOLID);
|
||||
scene::IMesh *mesh = node->getMesh();
|
||||
scene::IMesh *mesh = m_scene_manager->getGeometryCreator()
|
||||
->createSphereMesh(radius);
|
||||
|
||||
mesh->setMaterialFlag(video::EMF_COLOR_MATERIAL, true);
|
||||
video::SMaterial m;
|
||||
video::SMaterial &m = mesh->getMeshBuffer(0)->getMaterial();
|
||||
m.AmbientColor = color;
|
||||
m.DiffuseColor = color;
|
||||
m.EmissiveColor = color;
|
||||
m.BackfaceCulling = false;
|
||||
mesh->getMeshBuffer(0)->getMaterial() = m;
|
||||
m.MaterialType = video::EMT_SOLID;
|
||||
m.setTexture(0, getUnicolorTexture(video::SColor(128, 255, 105, 180)));
|
||||
m.setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0)));
|
||||
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
STKMeshSceneNode *node =
|
||||
new STKMeshSceneNode(mesh,
|
||||
m_scene_manager->getRootSceneNode(),
|
||||
NULL, -1, "sphere");
|
||||
return node;
|
||||
}
|
||||
|
||||
scene::IMeshSceneNode *node = m_scene_manager->addMeshSceneNode(mesh);
|
||||
return node;
|
||||
} // addSphere
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "graphics/show_curve.hpp"
|
||||
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
@ -64,6 +65,9 @@ void ShowCurve::addEmptyMesh()
|
||||
m_mesh = irr_driver->createQuadMesh(&m,
|
||||
/*create_one_quad*/ false);
|
||||
m_buffer = m_mesh->getMeshBuffer(0);
|
||||
m_buffer->getMaterial().setTexture(0, getUnicolorTexture(video::SColor(128, 255, 105, 180)));
|
||||
m_buffer->getMaterial().setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0)));
|
||||
|
||||
assert(m_buffer->getVertexType()==video::EVT_STANDARD);
|
||||
} // addEmptyMesh
|
||||
|
||||
|
@ -252,13 +252,16 @@ void fillLocalBuffer(GLMesh &mesh, scene::IMeshBuffer* mb)
|
||||
glGenBuffers(1, &(mesh.index_buffer));
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh.vertex_buffer);
|
||||
|
||||
const void* vertices = mb->getVertices();
|
||||
const u32 vertexCount = mb->getVertexCount();
|
||||
// This can happen for certain debug structures, e.g. ShowCurve
|
||||
if (vertexCount == 0)
|
||||
return;
|
||||
|
||||
const c8* vbuf = static_cast<const c8*>(vertices);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertexCount * mesh.Stride, vbuf,
|
||||
GL_STREAM_DRAW);
|
||||
assert(vertexCount);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.index_buffer);
|
||||
const void* indices = mb->getIndices();
|
||||
|
@ -417,10 +417,8 @@ void PlayerKartWidget::markAsReady()
|
||||
// 'playerNameString' is already fribidize, so we need to use
|
||||
// 'insertValues' and not _("...", a) so it's not flipped again
|
||||
m_ready_text =
|
||||
GUIEngine::getGUIEnv()->addStaticText(
|
||||
StringUtils::insertValues(_("%s is ready"),
|
||||
playerNameString).c_str(),
|
||||
rect );
|
||||
GUIEngine::getGUIEnv()->addStaticText(_("%s is ready", playerNameString),
|
||||
rect);
|
||||
m_ready_text->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER );
|
||||
|
||||
m_children.remove(m_player_ident_spinner);
|
||||
|
@ -19,24 +19,10 @@
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
//The AI debugging works best with just 1 AI kart, so set the number of karts
|
||||
//to 2 in main.cpp with quickstart and run supertuxkart with the arg -N.
|
||||
#ifdef DEBUG
|
||||
// Enable AI graphical debugging
|
||||
# undef AI_DEBUG
|
||||
// Shows left and right lines when using new findNonCrashing function
|
||||
# undef AI_DEBUG_NEW_FIND_NON_CRASHING
|
||||
// Show the predicted turn circles
|
||||
# undef AI_DEBUG_CIRCLES
|
||||
// Show the heading of the kart
|
||||
# undef AI_DEBUG_KART_HEADING
|
||||
// Shows line from kart to its aim point
|
||||
# undef AI_DEBUG_KART_AIM
|
||||
#endif
|
||||
|
||||
#include "karts/controller/skidding_ai.hpp"
|
||||
|
||||
#ifdef AI_DEBUG
|
||||
# include "graphics/glwrap.hpp"
|
||||
# include "graphics/irr_driver.hpp"
|
||||
#endif
|
||||
#include "graphics/show_curve.hpp"
|
||||
@ -111,6 +97,8 @@ SkiddingAI::SkiddingAI(AbstractKart *kart)
|
||||
i==2 ? 128 : 0);
|
||||
m_debug_sphere[i] = irr_driver->addSphere(1.0f, col_debug);
|
||||
m_debug_sphere[i]->setVisible(false);
|
||||
m_debug_sphere[i]->setMaterialTexture(0, getUnicolorTexture(video::SColor(128, 255, 105, 180)));
|
||||
m_debug_sphere[i]->setMaterialTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0)));
|
||||
}
|
||||
m_debug_sphere[m_point_selection_algorithm]->setVisible(true);
|
||||
m_item_sphere = irr_driver->addSphere(1.0f);
|
||||
@ -167,7 +155,7 @@ SkiddingAI::~SkiddingAI()
|
||||
{
|
||||
delete m_curve[i];
|
||||
}
|
||||
delete m_curve;
|
||||
delete [] m_curve;
|
||||
#endif
|
||||
} // ~SkiddingAI
|
||||
|
||||
@ -1843,7 +1831,7 @@ void SkiddingAI::findNonCrashingPointNew(Vec3 *result, int *last_node)
|
||||
m_curve[CURVE_RIGHT]->addPoint(q[RIGHT_END_POINT]+eps1);
|
||||
m_curve[CURVE_RIGHT]->addPoint(m_kart->getXYZ()+eps1);
|
||||
#endif
|
||||
#ifdef AI_DEBUG_KART_HEADING
|
||||
#if defined(AI_DEBUG_KART_HEADING) || defined(AI_DEBUG_NEW_FIND_NON_CRASHING)
|
||||
const Vec3 eps(0,0.5f,0);
|
||||
m_curve[CURVE_KART]->clear();
|
||||
m_curve[CURVE_KART]->addPoint(m_kart->getXYZ()+eps);
|
||||
|
@ -22,6 +22,27 @@
|
||||
#ifndef HEADER_SKIDDING_AI_HPP
|
||||
#define HEADER_SKIDDING_AI_HPP
|
||||
|
||||
// Some debugging features for the AI. For example you can visualise the
|
||||
// point the AI is aiming at, or visualise the curve the AI is predicting.
|
||||
// It works best with just 1 AI kart, so set the number of karts
|
||||
// to 2 in main.cpp with quickstart and run supertuxkart with the arg -N.
|
||||
// Or use --profile-laps=99 and run just one AI. Using the debug camera
|
||||
// (top view) is useful, too
|
||||
|
||||
#ifdef DEBUG
|
||||
// Enable AI graphical debugging
|
||||
# undef AI_DEBUG
|
||||
// Shows left and right lines when using new findNonCrashing function
|
||||
# undef AI_DEBUG_NEW_FIND_NON_CRASHING
|
||||
// Show the predicted turn circles
|
||||
# undef AI_DEBUG_CIRCLES
|
||||
// Show the heading of the kart
|
||||
# undef AI_DEBUG_KART_HEADING
|
||||
// Shows line from kart to its aim point
|
||||
# undef AI_DEBUG_KART_AIM
|
||||
#endif
|
||||
|
||||
|
||||
#include "karts/controller/ai_base_controller.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "tracks/graph_node.hpp"
|
||||
|
@ -166,6 +166,7 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
|
||||
m_boing_sound = SFXManager::get()->createSoundSource( "boing" );
|
||||
m_goo_sound = SFXManager::get()->createSoundSource( "goo" );
|
||||
m_skid_sound = SFXManager::get()->createSoundSource( "skid" );
|
||||
m_nitro_sound = SFXManager::get()->createSoundSource( "nitro" );
|
||||
m_terrain_sound = NULL;
|
||||
m_previous_terrain_sound = NULL;
|
||||
|
||||
@ -192,6 +193,7 @@ void Kart::init(RaceManager::KartType type)
|
||||
m_crash_sound->setVolume( 1.0f / factor );
|
||||
m_boing_sound->setVolume( 1.0f / factor );
|
||||
m_beep_sound->setVolume( 1.0f / factor );
|
||||
m_nitro_sound->setVolume( 1.0f / factor );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -200,6 +202,7 @@ void Kart::init(RaceManager::KartType type)
|
||||
m_crash_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_beep_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_boing_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_nitro_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,6 +259,7 @@ Kart::~Kart()
|
||||
m_goo_sound ->deleteSFX();
|
||||
m_beep_sound ->deleteSFX();
|
||||
m_boing_sound ->deleteSFX();
|
||||
m_nitro_sound ->deleteSFX();
|
||||
delete m_kart_gfx;
|
||||
if(m_terrain_sound) m_terrain_sound->deleteSFX();
|
||||
if(m_previous_terrain_sound) m_previous_terrain_sound->deleteSFX();
|
||||
@ -609,7 +613,7 @@ void Kart::createPhysics()
|
||||
// The y position of the wheels (i.e. the points where
|
||||
// the suspension is attached to) is just at the
|
||||
// bottom of the kart. That is half the kart height
|
||||
// down.
|
||||
// down.
|
||||
wheel_pos[index].setY(- 0.5f*kart_height);
|
||||
wheel_pos[index].setZ((0.5f*kart_length-0.25f)* z);
|
||||
|
||||
@ -1234,6 +1238,7 @@ void Kart::update(float dt)
|
||||
m_crash_sound->setPosition ( getXYZ() );
|
||||
m_skid_sound->setPosition ( getXYZ() );
|
||||
m_boing_sound->setPosition ( getXYZ() );
|
||||
m_nitro_sound->setPosition ( getXYZ() );
|
||||
|
||||
// Check if a kart is (nearly) upside down and not moving much -->
|
||||
// automatic rescue
|
||||
@ -1263,19 +1268,19 @@ void Kart::update(float dt)
|
||||
m_xyz_front = getTrans()(front);
|
||||
|
||||
// After the physics step was done, the position of the wheels (as stored
|
||||
// in wheelInfo) is actually outdated, since the chassis was moved
|
||||
// in wheelInfo) is actually outdated, since the chassis was moved
|
||||
// according to the force acting from the wheels. So the cnter of the
|
||||
// chassis is not at the center of the wheels anymore, it is somewhat
|
||||
// moved forward (depending on speed and fps). In very extreme cases
|
||||
// (see bug 2246) the center of the chassis can actually be ahead of the
|
||||
// front wheels. So if we do a raycast to detect the terrain from the
|
||||
// current chassis, that raycast might be ahead of the wheels - which
|
||||
// current chassis, that raycast might be ahead of the wheels - which
|
||||
// results in incorrect rescues (the wheels are still on the ground,
|
||||
// but the raycast happens ahead of the front wheels and are over
|
||||
// a rescue texture).
|
||||
// To avoid this problem, we do the raycast for terrain detection from
|
||||
// the center of the 4 wheel positions (in world coordinates).
|
||||
|
||||
|
||||
Vec3 from(0, 0, 0);
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
from += m_vehicle->getWheelInfo(i).m_raycastInfo.m_hardPointWS;
|
||||
@ -1747,23 +1752,35 @@ void Kart::updateNitro(float dt)
|
||||
bool increase_speed = (m_controls.m_nitro && isOnGround());
|
||||
if (!increase_speed && m_min_nitro_time <= 0.0f)
|
||||
{
|
||||
if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING)
|
||||
m_nitro_sound->stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_collected_energy -= dt * m_characteristic->getNitroConsumption();
|
||||
if (m_collected_energy < 0)
|
||||
{
|
||||
if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING)
|
||||
m_nitro_sound->stop();
|
||||
m_collected_energy = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (increase_speed)
|
||||
{
|
||||
if(m_nitro_sound->getStatus() != SFXBase::SFX_PLAYING)
|
||||
m_nitro_sound->play();
|
||||
m_max_speed->increaseMaxSpeed(MaxSpeed::MS_INCREASE_NITRO,
|
||||
m_characteristic->getNitroMaxSpeedIncrease(),
|
||||
m_characteristic->getNitroEngineForce(),
|
||||
m_characteristic->getNitroDuration(),
|
||||
m_characteristic->getNitroFadeOutTime());
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_nitro_sound->getStatus() == SFXBase::SFX_PLAYING)
|
||||
m_nitro_sound->stop();
|
||||
}
|
||||
} // updateNitro
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -2503,7 +2520,7 @@ void Kart::kartIsInRestNow()
|
||||
* physics-only simulation steps so that karts come to a rest). Then at
|
||||
* race time, only the difference between the current suspension length and
|
||||
* this default suspension length is used. The graphical kart chassis will be
|
||||
* offset so that when the kart is in rest, i.e. suspension length ==
|
||||
* offset so that when the kart is in rest, i.e. suspension length ==
|
||||
* default suspension length, the kart will look the way it was modelled in
|
||||
* blender. To explain the various offsets used, here a view from the side
|
||||
* focusing on the Y axis only (X/Z position of the graphical chassis is
|
||||
@ -2561,7 +2578,7 @@ void Kart::kartIsInRestNow()
|
||||
* and so not easily visible), so if the suspension is compressed by more than
|
||||
* that, the chassiswill appear to be in the ground. Testing on the sand track
|
||||
* shows that the suspension is compressed by 0.12 (and up to 0.16 in some
|
||||
* extreme points), which means that the chassis will appear to be in the
|
||||
* extreme points), which means that the chassis will appear to be in the
|
||||
* ground quite easily. Therefore the chassis is actually moved up a bit to
|
||||
* avoid this problem. Historically (due to never sorting out that formula
|
||||
* properly) the chassis was moved twice as high as its lowest point, e.g.
|
||||
@ -2571,7 +2588,7 @@ void Kart::kartIsInRestNow()
|
||||
* same amount higher.
|
||||
*
|
||||
* Of course this means that the Y position of the wheels (relative to the
|
||||
* visual kart chassis) needs to be adjusted: if the kart is in rest, the
|
||||
* visual kart chassis) needs to be adjusted: if the kart is in rest, the
|
||||
* wheels are exactly on the ground. If the suspension is shorter, that wheel
|
||||
* would appear to be partly in the ground, and if the suspension is longer,
|
||||
* the wheel would not touch the ground.
|
||||
@ -2579,7 +2596,7 @@ void Kart::kartIsInRestNow()
|
||||
* The wheels must be offset by how much the current suspension length is
|
||||
* longer or shorter than the default (i.e. at rest) suspension length.
|
||||
* This is done in KartModel (pos is the position of the wheel relative
|
||||
* to the visual kart chassis):
|
||||
* to the visual kart chassis):
|
||||
* pos.Y += m_default_physics_suspension[i]
|
||||
* - wi.m_raycastInfo.m_suspensionLength
|
||||
* But since the chassis is raised an additional 'getLowestPoint' (see
|
||||
@ -2692,7 +2709,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
|
||||
if (m_shadow)
|
||||
{
|
||||
const bool emergency = getKartAnimation() != NULL;
|
||||
m_shadow->update(isOnGround() && !emergency,
|
||||
m_shadow->update(isOnGround() && !emergency,
|
||||
m_terrain_info->getHoT() - getXYZ().getY()
|
||||
- m_skidding->getGraphicalJumpOffset()
|
||||
- m_graphical_y_offset
|
||||
@ -2750,7 +2767,7 @@ void Kart::setOnScreenText(const wchar_t *text)
|
||||
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
gui::ScalableFont* font = GUIEngine::getFont() ? GUIEngine::getFont()
|
||||
gui::ScalableFont* font = GUIEngine::getFont() ? GUIEngine::getFont()
|
||||
: GUIEngine::getTitleFont();
|
||||
new STKTextBillboard(text, font,
|
||||
video::SColor(255, 255, 225, 0),
|
||||
|
@ -148,7 +148,7 @@ private:
|
||||
|
||||
/** True if fire button was pushed and not released */
|
||||
bool m_fire_clicked;
|
||||
|
||||
|
||||
/** Counter which is used for displaying wrong way message after a delay */
|
||||
float m_wrongway_counter;
|
||||
|
||||
@ -199,6 +199,7 @@ private:
|
||||
SFXBase *m_engine_sound;
|
||||
SFXBase *m_crash_sound;
|
||||
SFXBase *m_terrain_sound;
|
||||
SFXBase *m_nitro_sound;
|
||||
/** A pointer to the previous terrain sound needs to be saved so that an
|
||||
* 'older' sfx can be finished and an abrupt end of the sfx is avoided. */
|
||||
SFXBase *m_previous_terrain_sound;
|
||||
|
@ -267,7 +267,7 @@ public:
|
||||
*/
|
||||
core::stringw getName() const
|
||||
{
|
||||
return core::stringw(translations->w_gettext(m_name.c_str()));
|
||||
return _LTR(m_name.c_str());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -199,9 +199,8 @@ void EasterEggHunt::getKartsDisplayInfo(
|
||||
{
|
||||
RaceGUIBase::KartIconDisplayInfo& rank_info = (*info)[i];
|
||||
//I18n: number of collected eggs / overall number of eggs
|
||||
rank_info.m_text = StringUtils::insertValues(_("Eggs: %d / %d"),
|
||||
m_eggs_collected[i],
|
||||
m_number_of_eggs);
|
||||
rank_info.m_text = _("Eggs: %d / %d", m_eggs_collected[i],
|
||||
m_number_of_eggs);
|
||||
rank_info.m_color = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
} // getKartDisplayInfo
|
||||
|
@ -173,7 +173,14 @@ void LinearWorld::update(float dt)
|
||||
// Nothing to do for karts that are currently being
|
||||
// rescued or eliminated
|
||||
if(kart->getKartAnimation()) continue;
|
||||
|
||||
// If the kart is off road, and 'flying' over a reset plane
|
||||
// don't adjust the distance of the kart, to avoid a jump
|
||||
// in the position of the kart (e.g. while falling the kart
|
||||
// might get too close to another part of the track, shortly
|
||||
// jump to position one, then on reset fall back to last)
|
||||
if (!kart_info.getTrackSector()->isOnRoad() &&
|
||||
kart->getMaterial()->isDriveReset())
|
||||
continue;
|
||||
kart_info.getTrackSector()->update(kart->getFrontXYZ());
|
||||
kart_info.m_overall_distance = kart_info.m_race_lap
|
||||
* m_track->getTrackLength()
|
||||
|
@ -167,8 +167,8 @@ public:
|
||||
// -------------------------------------------------------------------------
|
||||
enum GPReverseType getReverseType()
|
||||
const { return m_reverse_type; }
|
||||
static const char* getRandomGPID() { return "random"; }
|
||||
static const wchar_t* getRandomGPName() { return _LTR("Random Grand Prix");}
|
||||
static const char* getRandomGPID() { return "random"; }
|
||||
static irr::core::stringw getRandomGPName() { return _LTR("Random Grand Prix"); }
|
||||
}; // GrandPrixData
|
||||
|
||||
#endif
|
||||
|
@ -168,7 +168,7 @@ public:
|
||||
/** Returns a (translated) name of a minor race mode.
|
||||
* \param mode Minor race mode.
|
||||
*/
|
||||
static const wchar_t* getNameOf(const MinorRaceModeType mode)
|
||||
static const core::stringw getNameOf(const MinorRaceModeType mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
@ -184,7 +184,7 @@ public:
|
||||
case MINOR_MODE_EASTER_EGG: return _("Egg Hunt");
|
||||
//I18N: Game mode
|
||||
case MINOR_MODE_SOCCER: return _("Soccer");
|
||||
default: assert(false); return NULL;
|
||||
default: assert(false); return L"";
|
||||
}
|
||||
} // getNameOf
|
||||
|
||||
|
@ -356,9 +356,8 @@ void AddonsLoading::doInstall()
|
||||
bool error = !addons_manager->install(m_addon);
|
||||
if(error)
|
||||
{
|
||||
core::stringw msg = StringUtils::insertValues(
|
||||
_("Problems installing the addon '%s'."),
|
||||
core::stringw(m_addon.getName().c_str()));
|
||||
const core::stringw &name = m_addon.getName();
|
||||
core::stringw msg = _("Problems installing the addon '%s'.", name);
|
||||
getWidget<BubbleWidget>("description")->setText(msg.c_str());
|
||||
}
|
||||
|
||||
@ -394,8 +393,8 @@ void AddonsLoading::doUninstall()
|
||||
Log::warn("Addons", "Directory '%s' can not be removed.",
|
||||
m_addon.getDataDir().c_str());
|
||||
Log::warn("Addons", "Please remove this directory manually.");
|
||||
core::stringw msg = StringUtils::insertValues(_("Problems removing the addon '%s'."),
|
||||
core::stringw(m_addon.getName().c_str()));
|
||||
const core::stringw &name = m_addon.getName();
|
||||
core::stringw msg = _("Problems removing the addon '%s'.", name);
|
||||
getWidget<BubbleWidget>("description")->setText(msg.c_str());
|
||||
}
|
||||
|
||||
|
@ -98,10 +98,6 @@ RaceGUIBase::RaceGUIBase()
|
||||
m_dist_show_overlap = 2;
|
||||
m_icons_inertia = 2;
|
||||
|
||||
|
||||
//I18N: When some GlobalPlayerIcons are hidden, write "Top 10" to show it
|
||||
m_string_top = _("Top %i");
|
||||
|
||||
m_referee = NULL;
|
||||
} // RaceGUIBase
|
||||
|
||||
@ -812,7 +808,8 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
|
||||
static video::SColor color = video::SColor(255, 255, 255, 255);
|
||||
pos_top.LowerRightCorner = pos_top.UpperLeftCorner;
|
||||
|
||||
font->draw(StringUtils::insertValues( m_string_top, position-1 ), pos_top, color);
|
||||
//I18N: When some GlobalPlayerIcons are hidden, write "Top 10" to show it
|
||||
font->draw(_("Top %i", position-1 ), pos_top, color);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -129,9 +129,6 @@ private:
|
||||
/** Translated strings 'ready', 'set', 'go'. */
|
||||
core::stringw m_string_ready, m_string_set, m_string_go, m_string_goal;
|
||||
|
||||
/** Translated string 'Top %d' displayed every frame. */
|
||||
core::stringw m_string_top;
|
||||
|
||||
/** The position of the referee for all karts. */
|
||||
std::vector<Vec3> m_referee_pos;
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "modes/linear_world.hpp"
|
||||
@ -77,6 +78,7 @@ CheckLine::CheckLine(const XMLNode &node, unsigned int index)
|
||||
scene::IMesh *mesh = irr_driver->createQuadMesh(&material,
|
||||
/*create mesh*/true);
|
||||
scene::IMeshBuffer *buffer = mesh->getMeshBuffer(0);
|
||||
|
||||
assert(buffer->getVertexType()==video::EVT_STANDARD);
|
||||
irr::video::S3DVertex* vertices
|
||||
= (video::S3DVertex*)buffer->getVertices();
|
||||
@ -95,11 +97,14 @@ CheckLine::CheckLine(const XMLNode &node, unsigned int index)
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
vertices[i].Color = m_active_at_reset
|
||||
? video::SColor(0, 255, 0, 0)
|
||||
: video::SColor(0, 128, 128, 128);
|
||||
? video::SColor(128, 255, 0, 0)
|
||||
: video::SColor(128, 128, 128, 128);
|
||||
}
|
||||
buffer->recalculateBoundingBox();
|
||||
mesh->setBoundingBox(buffer->getBoundingBox());
|
||||
buffer->getMaterial().setTexture(0, getUnicolorTexture(video::SColor(128, 255, 105, 180)));
|
||||
buffer->getMaterial().setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0)));
|
||||
buffer->getMaterial().BackfaceCulling = false;
|
||||
//mesh->setBoundingBox(buffer->getBoundingBox());
|
||||
m_debug_node = irr_driver->addMesh(mesh, "checkdebug");
|
||||
mesh->drop();
|
||||
}
|
||||
@ -137,11 +142,14 @@ void CheckLine::changeDebugColor(bool is_active)
|
||||
scene::IMeshBuffer *buffer = mesh->getMeshBuffer(0);
|
||||
irr::video::S3DVertex* vertices
|
||||
= (video::S3DVertex*)buffer->getVertices();
|
||||
video::SColor color = is_active ? video::SColor(192, 255, 0, 0)
|
||||
: video::SColor(192, 128, 128, 128);
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
vertices[i].Color = is_active ? video::SColor(0, 255, 0, 0)
|
||||
: video::SColor(0, 128, 128, 128);
|
||||
vertices[i].Color = color;
|
||||
}
|
||||
buffer->getMaterial().setTexture(0, getUnicolorTexture(color));
|
||||
|
||||
} // changeDebugColor
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -310,7 +310,7 @@ void TrackObject::onWorldReady()
|
||||
|
||||
fn_signature << "bool " << fn_name << "(";
|
||||
|
||||
for (int i = 0; i < arguments.size(); i++)
|
||||
for (unsigned int i = 0; i < arguments.size(); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
fn_signature << ",";
|
||||
@ -328,7 +328,7 @@ void TrackObject::onWorldReady()
|
||||
script_engine->runFunction(true, fn_signature.str(),
|
||||
[&](asIScriptContext* ctx)
|
||||
{
|
||||
for (int i = 0; i < arguments.size(); i++)
|
||||
for (unsigned int i = 0; i < arguments.size(); i++)
|
||||
{
|
||||
ctx->SetArgObject(i, &arguments[i]);
|
||||
}
|
||||
|
@ -25,12 +25,13 @@
|
||||
#include "utils/utf8.h"
|
||||
#include "coreutil.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <cwchar>
|
||||
#include <exception>
|
||||
#include <assert.h>
|
||||
|
||||
namespace StringUtils
|
||||
{
|
||||
@ -167,7 +168,7 @@ namespace StringUtils
|
||||
try
|
||||
{
|
||||
std::string::size_type start=0;
|
||||
while(start!=std::string::npos && start<(unsigned int)s.size())
|
||||
while(start < (unsigned int) s.size())
|
||||
{
|
||||
std::string::size_type i=s.find(c, start);
|
||||
if (i!=std::string::npos)
|
||||
@ -185,11 +186,11 @@ namespace StringUtils
|
||||
}
|
||||
else // end of string reached
|
||||
{
|
||||
if (keepSplitChar)
|
||||
if (keepSplitChar && start != 0)
|
||||
result.push_back(std::string(s,start-1));
|
||||
else
|
||||
result.push_back(std::string(s,start));
|
||||
start = i;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -243,14 +244,13 @@ namespace StringUtils
|
||||
}
|
||||
else
|
||||
{
|
||||
if (keepSplitChar)
|
||||
if (keepSplitChar && start != 0)
|
||||
result.push_back( s.subString(start - 1,
|
||||
s.size()-start + 1) );
|
||||
else
|
||||
result.push_back( s.subString(start, s.size()-start) );
|
||||
|
||||
return result;
|
||||
//start = i+1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -136,210 +136,71 @@ namespace StringUtils
|
||||
std::string insertValues(const std::string &s,
|
||||
std::vector<std::string>& all_vals);
|
||||
|
||||
/** This no-op is useful when using variadic arguments, so that we may
|
||||
* support the case with 0 variadic arguments */
|
||||
template <class T1>
|
||||
T1 insertValues(const T1& s) { return s; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Same as above but for wide-strings */
|
||||
irr::core::stringw insertValues(const irr::core::stringw &s,
|
||||
std::vector<irr::core::stringw>& all_vals);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Note: the order in which the templates are specified is important, since
|
||||
// otherwise some compilers will not find the right template to use.
|
||||
|
||||
template <class T1, class T2, class T3, class T4, class T5, class T6>
|
||||
std::string insertValues(const std::string &s, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3, const T4 &v4,
|
||||
const T5 &v5,const T6 &v6)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
std::ostringstream dummy;
|
||||
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v3; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v4; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v5; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v6; all_vals.push_back(dummy.str());
|
||||
return insertValues(s, all_vals);
|
||||
} // insertValues(s, v1, ..., v6)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template <class T1, class T2, class T3, class T4, class T5>
|
||||
std::string insertValues(const std::string &s, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3, const T4 &v4,
|
||||
const T5 &v5)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
std::ostringstream dummy;
|
||||
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v3; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v4; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v5; all_vals.push_back(dummy.str());
|
||||
return insertValues(s, all_vals);
|
||||
} // insertValues(s, v1, ..., v5)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
std::string insertValues(const std::string &s, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3, const T4 &v4)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
std::ostringstream dummy;
|
||||
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v3; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v4; all_vals.push_back(dummy.str());
|
||||
return insertValues(s, all_vals);
|
||||
} // insertValues(s, v1, ..., v4)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Shortcut insert_values taking three values, see above for
|
||||
* full docs.
|
||||
* \param s String in which all %s or %d are replaced.
|
||||
* \param v1,v2, v3 Value(s) to replace all %s or %d with.
|
||||
*/
|
||||
template <class T1, class T2, class T3>
|
||||
std::string insertValues(const std::string &s, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
std::ostringstream dummy;
|
||||
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v3; all_vals.push_back(dummy.str());
|
||||
return insertValues(s, all_vals);
|
||||
} // insertValues(s, v1, ..., v3)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Note: the order in which the templates are specified is important, since
|
||||
// otherwise some compilers will not find the right template to use.
|
||||
/** Shortcut insert_values taking three values, see above for
|
||||
* full docs.
|
||||
* \param s String in which all %s or %d are replaced.
|
||||
* \param v1,v2 Value(s) to replace all %s or %d with.
|
||||
*/
|
||||
template <class T1, class T2>
|
||||
std::string insertValues(const std::string &s, const T1 &v1,
|
||||
const T2 &v2)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
std::ostringstream dummy;
|
||||
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
|
||||
return insertValues(s, all_vals);
|
||||
} // insertValues(s, v1, v2)
|
||||
// ------------------------------------------------------------------------
|
||||
/** Shortcut insert_values taking three values, see above for
|
||||
* full docs.
|
||||
* \param s String in which all %s, %d are replaced.
|
||||
* \param v1 Value to replace.
|
||||
*/
|
||||
template <class T1>
|
||||
std::string insertValues(const std::string &s, const T1 &v1)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
std::ostringstream dummy;
|
||||
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
|
||||
return insertValues(s, all_vals);
|
||||
} // insertValues(s, v1)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Intermediate struct to fill a vector using variadic templates */
|
||||
struct __FillStringwVector
|
||||
struct FillStringVector
|
||||
{
|
||||
/** FillS takes a vector as the first argument and a variadic list of
|
||||
* arguments. The arguments are recursively inserted into the vector
|
||||
* which will contain all the arguments converted to strings in the end.
|
||||
*/
|
||||
template<typename T, typename...Args>
|
||||
static void __Fill(std::vector<irr::core::stringw> &all_vals, T&& v, Args &&...args)
|
||||
static void FillS(std::vector<std::string> &all_vals, T&& v, Args &&...args)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << v;
|
||||
all_vals.push_back(oss.str());
|
||||
FillS(all_vals, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static void FillS(std::vector<std::string>&) {}
|
||||
|
||||
/** This functions does the same as FillS but for wide strings. */
|
||||
template<typename T, typename...Args>
|
||||
static void FillW(std::vector<irr::core::stringw> &all_vals, T&& v, Args &&...args)
|
||||
{
|
||||
all_vals.push_back(irr::core::stringw(std::forward<T>(v)));
|
||||
__Fill(all_vals, std::forward<Args>(args)...);
|
||||
FillW(all_vals, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static void __Fill(std::vector<irr::core::stringw>&) {}
|
||||
|
||||
static void FillW(std::vector<irr::core::stringw>&) {}
|
||||
};
|
||||
|
||||
template <typename...Args>
|
||||
std::string insertValues(const std::string &s, Args ...args)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
all_vals.reserve(sizeof...(args));
|
||||
FillStringVector::FillS(all_vals, std::forward<Args>(args)...);
|
||||
return insertValues(s, all_vals);
|
||||
}
|
||||
|
||||
template <typename...Args>
|
||||
std::string insertValues(const char *s, Args ...args)
|
||||
{
|
||||
return insertValues(std::string(s), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/** Like the other ones above but for wide strings */
|
||||
template <typename...Args>
|
||||
irr::core::stringw insertValues(const irr::core::stringw &s, Args ...args)
|
||||
{
|
||||
std::vector<irr::core::stringw> all_vals;
|
||||
__FillStringwVector::__Fill(all_vals, std::forward<Args>(args)...);
|
||||
all_vals.reserve(sizeof...(args));
|
||||
FillStringVector::FillW(all_vals, std::forward<Args>(args)...);
|
||||
return insertValues(s, all_vals);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for wide strings */
|
||||
template <class T1, class T2, class T3, class T4, class T5>
|
||||
irr::core::stringw insertValues(const wchar_t* chars, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3, const T4 &v4,
|
||||
const T5 &v5)
|
||||
template <typename...Args>
|
||||
irr::core::stringw insertValues(const wchar_t *s, Args ...args)
|
||||
{
|
||||
irr::core::stringw s(chars);
|
||||
return insertValues(s, v1, v2, v3, v4, v5);
|
||||
} // insertValues(s, v1, ..., v5)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for wide strings */
|
||||
template <class T1, class T2, class T3>
|
||||
irr::core::stringw insertValues(const wchar_t* chars, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3)
|
||||
{
|
||||
irr::core::stringw s(chars);
|
||||
return insertValues(s, v1, v2, v3);
|
||||
} // insertValues(s, v1, ..., v3)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for wide strings */
|
||||
template <class T1, class T2>
|
||||
irr::core::stringw insertValues(const wchar_t* chars, const T1 &v1,
|
||||
const T2 &v2)
|
||||
{
|
||||
irr::core::stringw s(chars);
|
||||
return insertValues(s, v1, v2);
|
||||
} // insertValues(s, v1, v2)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for wide strings */
|
||||
template <class T1>
|
||||
irr::core::stringw insertValues(const wchar_t* chars, const T1 &v1)
|
||||
{
|
||||
irr::core::stringw s(chars);
|
||||
return insertValues(s, v1);
|
||||
} // insertValues(s, v1)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for C strings */
|
||||
template <class T1, class T2, class T3>
|
||||
std::string insertValues(const char* chars, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3)
|
||||
{
|
||||
std::string s(chars);
|
||||
return insertValues(s, v1, v2, v3);
|
||||
} // insertValues(s, v1, ..., v3)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for C strings */
|
||||
template <class T1, class T2>
|
||||
std::string insertValues(const char* chars, const T1 &v1,
|
||||
const T2 &v2)
|
||||
{
|
||||
std::string s(chars);
|
||||
return insertValues(s, v1, v2);
|
||||
} // insertValues(s, v1, v2)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for C strings */
|
||||
template <class T1>
|
||||
std::string insertValues(const char* chars, const T1 &v1)
|
||||
{
|
||||
std::string s(chars);
|
||||
return insertValues(s, v1);
|
||||
} // insertValues(s, v1)
|
||||
return insertValues(irr::core::stringw(s), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
@ -371,5 +232,3 @@ namespace StringUtils
|
||||
} // namespace StringUtils
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
@ -26,12 +26,13 @@
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <cassert>
|
||||
#include <cerrno>
|
||||
#include <clocale>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cwchar>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
@ -359,10 +360,23 @@ Translations::Translations() //: m_dictionary_manager("UTF-16")
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Translations::~Translations()
|
||||
{
|
||||
} // ~Translations
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const wchar_t* Translations::fribidize(const wchar_t* in_ptr)
|
||||
{
|
||||
if (isRTLText(in_ptr))
|
||||
{
|
||||
// Test if this string was already fribidized
|
||||
std::map<const irr::core::stringw, const irr::core::stringw>::const_iterator
|
||||
found = m_fribidized_strings.find(in_ptr);
|
||||
if (found != m_fribidized_strings.cend())
|
||||
return found->second.c_str();
|
||||
|
||||
// Use fribidi to fribidize the string
|
||||
// Split text into lines
|
||||
std::vector<core::stringw> input_lines = StringUtils::split(in_ptr, '\n');
|
||||
// Reverse lines for RTL strings, irrlicht will reverse them back
|
||||
@ -371,18 +385,25 @@ const wchar_t* Translations::fribidize(const wchar_t* in_ptr)
|
||||
std::reverse(input_lines.begin(), input_lines.end());
|
||||
|
||||
// Fribidize and concat lines
|
||||
core::stringw converted_string;
|
||||
for (std::vector<core::stringw>::iterator it = input_lines.begin();
|
||||
it != input_lines.end(); it++)
|
||||
{
|
||||
if (it == input_lines.begin())
|
||||
m_converted_string = fribidizeLine(*it);
|
||||
converted_string = fribidizeLine(*it);
|
||||
else
|
||||
{
|
||||
m_converted_string += "\n";
|
||||
m_converted_string += fribidizeLine(*it);
|
||||
converted_string += "\n";
|
||||
converted_string += fribidizeLine(*it);
|
||||
}
|
||||
}
|
||||
return m_converted_string.c_str();
|
||||
|
||||
// Save it in the map
|
||||
m_fribidized_strings.insert(std::pair<const irr::core::stringw, const irr::core::stringw>(
|
||||
in_ptr, converted_string));
|
||||
found = m_fribidized_strings.find(in_ptr);
|
||||
|
||||
return found->second.c_str();
|
||||
}
|
||||
else
|
||||
return in_ptr;
|
||||
@ -448,12 +469,13 @@ const wchar_t* Translations::w_gettext(const char* original, const char* context
|
||||
|
||||
if (original_t == original)
|
||||
{
|
||||
m_converted_string = StringUtils::utf8_to_wide(original);
|
||||
static irr::core::stringw converted_string;
|
||||
converted_string = StringUtils::utf8_to_wide(original);
|
||||
|
||||
#if TRANSLATE_VERBOSE
|
||||
std::wcout << L" translation : " << m_converted_string << std::endl;
|
||||
std::wcout << L" translation : " << converted_string << std::endl;
|
||||
#endif
|
||||
return m_converted_string.c_str();
|
||||
return converted_string.c_str();
|
||||
}
|
||||
|
||||
// print
|
||||
@ -572,4 +594,3 @@ core::stringw Translations::fribidizeLine(const core::stringw &str)
|
||||
return core::stringw(str);
|
||||
#endif // ENABLE_BIDI
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,14 @@
|
||||
#define TRANSLATION_HPP
|
||||
|
||||
#include <irrString.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
# include "tinygettext/tinygettext.hpp"
|
||||
#include "tinygettext/tinygettext.hpp"
|
||||
|
||||
# define _(String, ...) (translations->fribidize(StringUtils::insertValues(translations->w_gettext(String), ##__VA_ARGS__)))
|
||||
#undef _C
|
||||
@ -46,13 +49,15 @@ private:
|
||||
tinygettext::DictionaryManager m_dictionary_manager;
|
||||
tinygettext::Dictionary m_dictionary;
|
||||
|
||||
irr::core::stringw m_converted_string;
|
||||
/** A map that saves all fribidized strings: Original string, fribidized string */
|
||||
std::map<const irr::core::stringw, const irr::core::stringw> m_fribidized_strings;
|
||||
bool m_rtl;
|
||||
|
||||
std::string m_current_language_name;
|
||||
|
||||
public:
|
||||
Translations();
|
||||
~Translations();
|
||||
|
||||
const wchar_t *w_gettext(const wchar_t* original, const char* context=NULL);
|
||||
const wchar_t *w_gettext(const char* original, const char* context=NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user