Merged changes from trunk.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/battleAI@14293 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
BIN
data/CREDITS
BIN
data/CREDITS
Binary file not shown.
@@ -12,7 +12,7 @@
|
||||
<bright proportion="1" height="100%"
|
||||
I18N="In soccer setup menu" text="Number of goals to win" text_align="right" />
|
||||
<spacer width="50" height="25"/>
|
||||
<spinner id="goalamount" proportion="1" height="100%" min_value="1" max_value="30" wrap_around="true"/>
|
||||
<spinner id="goalamount" proportion="1" height="100%" min_value="1" max_value="10" wrap_around="true"/>
|
||||
</div>
|
||||
|
||||
<spacer height="25" width="25"/>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<material name="stk_mod_nitroBottle.png" />
|
||||
<material name="stk_mod_nitroLogo.png" compositing="additive" light="N" disable-z-write="Y" />
|
||||
|
||||
<material name="bubblegum_shield.png" compositing="blend" sphere="Y"/>
|
||||
<material name="bubblegum_shield.png" compositing="blend" disable-z-write="Y"/>
|
||||
<material name="parachute.png" backface-culling="n" ignore="Y"/>
|
||||
<material name="zipper.png" light="N" zipper="Y"/>
|
||||
<material name="zipper_collect.png" light="N" zipper="Y"/>
|
||||
|
||||
@@ -253,6 +253,8 @@
|
||||
disable-slipstream-usage: even if the AI is not trying to use slipstream,
|
||||
it can get a lot of bonus, esp. on easy since the AI creates trains.
|
||||
Set this to true to make sure AI does not get any slipstream bonus.
|
||||
shield-incoming-radius: Radius at which projectiles will be detected and
|
||||
trigger a shield usage.
|
||||
false-start-probability: Probability of a false start.
|
||||
min/max-start-delay: Minimum and maximum start delay.
|
||||
See http://www.humanbenchmark.com/tests/reactiontime/stats.php
|
||||
@@ -316,6 +318,7 @@
|
||||
straight-length-for-zipper="35"
|
||||
use-slipstream="false"
|
||||
disable-slipstream-usage="true"
|
||||
shield-incoming-radius="0"
|
||||
false-start-probability="0.08"
|
||||
min-start-delay="0.3" max-start-delay="0.5"
|
||||
nitro-usage="none"
|
||||
@@ -333,6 +336,7 @@
|
||||
straight-length-for-zipper="35"
|
||||
use-slipstream="false"
|
||||
disable-slipstream-usage="false"
|
||||
shield-incoming-radius="10"
|
||||
false-start-probability="0.04"
|
||||
min-start-delay="0.25" max-start-delay="0.4"
|
||||
nitro-usage="some"
|
||||
@@ -350,6 +354,7 @@
|
||||
straight-length-for-zipper="35"
|
||||
use-slipstream="true"
|
||||
disable-slipstream-usage="false"
|
||||
shield-incoming-radius="10"
|
||||
false-start-probability="0.01"
|
||||
min-start-delay="0.15" max-start-delay="0.28"
|
||||
nitro-usage="all"
|
||||
@@ -367,6 +372,7 @@
|
||||
straight-length-for-zipper="35"
|
||||
use-slipstream="true"
|
||||
disable-slipstream-usage="false"
|
||||
shield-incoming-radius="10"
|
||||
false-start-probability="0.0"
|
||||
min-start-delay="0.15" max-start-delay="0.2"
|
||||
nitro-usage="all"
|
||||
@@ -477,6 +483,11 @@
|
||||
<rear-right position="0.38 0 -0.6" />
|
||||
<rear-left position="-0.38 0 -0.6"/>
|
||||
</wheels>
|
||||
|
||||
<!-- Parameters for the speed-weighted objects:
|
||||
a bigger value for strength-factor leads to the speed of the kart more quickly affecting
|
||||
the strength of the animation (up to a maximum value that corresponds to the original animation) -->
|
||||
<speed-weighted strength-factor="0.05" speed-factor="5.0"/>
|
||||
|
||||
<!-- friction: slip used for bullet skidding. A high value
|
||||
(like 10000000) disables bullet skidding. -->
|
||||
|
||||
@@ -15,7 +15,7 @@ endif()
|
||||
add_definitions(-DNDEBUG=1 -DIRRLICHT_EXPORTS=1 -DPNG_THREAD_UNSAFE_OK -DPNG_NO_MMX_CODE -DPNG_NO_MNG_FEATURES)
|
||||
if(MSVC)
|
||||
add_definitions(/D_IRR_STATIC_LIB_)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" /MTd)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MTd")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fno-rtti -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fno-rtti -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include")
|
||||
|
||||
@@ -86,6 +86,14 @@ namespace scene
|
||||
/** \return Frames per second played. */
|
||||
virtual f32 getAnimationSpeed() const =0;
|
||||
|
||||
//! Sets the animation strength (how important the animation is)
|
||||
/** \param strength: The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */
|
||||
virtual void setAnimationStrength(f32 strength) =0;
|
||||
|
||||
//! Gets the animation strength (how important the animation is)
|
||||
/** \return The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */
|
||||
virtual f32 getAnimationStrength() const =0;
|
||||
|
||||
//! Creates shadow volume scene node as child of this node.
|
||||
/** The shadow can be rendered using the ZPass or the zfail
|
||||
method. ZPass is a little bit faster because the shadow volume
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace scene
|
||||
virtual void animateMesh(f32 frame, f32 blend)=0;
|
||||
|
||||
//! Preforms a software skin on this mesh based of joint positions
|
||||
virtual void skinMesh() = 0;
|
||||
virtual void skinMesh(f32 strength=1.f) = 0;
|
||||
|
||||
//! converts the vertex type of all meshbuffers to tangents.
|
||||
/** E.g. used for bump mapping. */
|
||||
|
||||
@@ -33,7 +33,7 @@ CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh* mesh,
|
||||
const core::vector3df& scale)
|
||||
: IAnimatedMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0),
|
||||
StartFrame(0), EndFrame(0), FramesPerSecond(0.025f),
|
||||
CurrentFrameNr(0.f), LastTimeMs(0),
|
||||
CurrentFrameNr(0.f), AnimationStrength(1.f), LastTimeMs(0),
|
||||
TransitionTime(0), Transiting(0.f), TransitingBlend(0.f),
|
||||
JointMode(EJUOR_NONE), JointsUsed(false),
|
||||
Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(false),
|
||||
@@ -210,7 +210,7 @@ IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame()
|
||||
skinnedMesh->animateMesh(getFrameNr(), 1.0f);
|
||||
|
||||
// Update the skinned mesh for the current joint transforms.
|
||||
skinnedMesh->skinMesh();
|
||||
skinnedMesh->skinMesh(AnimationStrength);
|
||||
|
||||
if (JointMode == EJUOR_READ)//read from mesh
|
||||
{
|
||||
@@ -516,6 +516,21 @@ f32 CAnimatedMeshSceneNode::getAnimationSpeed() const
|
||||
}
|
||||
|
||||
|
||||
//! Sets the animation strength (how important the animation is)
|
||||
/** \param strength: The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */
|
||||
void CAnimatedMeshSceneNode::setAnimationStrength(f32 strength)
|
||||
{
|
||||
AnimationStrength = strength;
|
||||
}
|
||||
|
||||
//! Gets the animation strength (how important the animation is)
|
||||
/** \return The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */
|
||||
f32 CAnimatedMeshSceneNode::getAnimationStrength() const
|
||||
{
|
||||
return AnimationStrength;
|
||||
}
|
||||
|
||||
|
||||
//! returns the axis aligned bounding box of this node
|
||||
const core::aabbox3d<f32>& CAnimatedMeshSceneNode::getBoundingBox() const
|
||||
{
|
||||
|
||||
@@ -66,6 +66,14 @@ namespace scene
|
||||
//! gets the speed with which the animation is played
|
||||
virtual f32 getAnimationSpeed() const;
|
||||
|
||||
//! Sets the animation strength (how important the animation is)
|
||||
/** \param strength: The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */
|
||||
virtual void setAnimationStrength(f32 strength);
|
||||
|
||||
//! Gets the animation strength (how important the animation is)
|
||||
/** \return The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */
|
||||
virtual f32 getAnimationStrength() const;
|
||||
|
||||
//! returns the material based on the zero based index i. To get the amount
|
||||
//! of materials used by this scene node, use getMaterialCount().
|
||||
//! This function is needed for inserting the node into the scene hirachy on a
|
||||
@@ -183,6 +191,8 @@ namespace scene
|
||||
f32 FramesPerSecond;
|
||||
f32 CurrentFrameNr;
|
||||
|
||||
f32 AnimationStrength;
|
||||
|
||||
u32 LastTimeMs;
|
||||
u32 TransitionTime; //Transition time in millisecs
|
||||
f32 Transiting; //is mesh transiting (plus cache of TransitionTime)
|
||||
|
||||
@@ -445,7 +445,7 @@ void CSkinnedMesh::getFrameData(f32 frame, SJoint *joint,
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
//! Preforms a software skin on this mesh based of joint positions
|
||||
void CSkinnedMesh::skinMesh()
|
||||
void CSkinnedMesh::skinMesh(f32 strength)
|
||||
{
|
||||
if (!HasAnimation || SkinnedLastFrame)
|
||||
return;
|
||||
@@ -478,7 +478,7 @@ void CSkinnedMesh::skinMesh()
|
||||
|
||||
//skin starting with the root joints
|
||||
for (i=0; i<RootJoints.size(); ++i)
|
||||
skinJoint(RootJoints[i], 0);
|
||||
skinJoint(RootJoints[i], 0, strength);
|
||||
|
||||
for (i=0; i<SkinningBuffers->size(); ++i)
|
||||
(*SkinningBuffers)[i]->setDirty(EBT_VERTEX);
|
||||
@@ -486,8 +486,7 @@ void CSkinnedMesh::skinMesh()
|
||||
updateBoundingBox();
|
||||
}
|
||||
|
||||
|
||||
void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint)
|
||||
void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint, f32 strength)
|
||||
{
|
||||
if (joint->Weights.size())
|
||||
{
|
||||
@@ -510,6 +509,14 @@ void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint)
|
||||
if (AnimateNormals)
|
||||
jointVertexPull.rotateVect(thisNormalMove, weight.StaticNormal);
|
||||
|
||||
// Apply animation strength
|
||||
if(strength != 1.f)
|
||||
{
|
||||
thisVertexMove = core::lerp(weight.StaticPos, thisVertexMove, strength);
|
||||
if(AnimateNormals)
|
||||
thisNormalMove = core::lerp(weight.StaticNormal, thisNormalMove, strength);
|
||||
}
|
||||
|
||||
if (! (*(weight.Moved)) )
|
||||
{
|
||||
*(weight.Moved) = true;
|
||||
@@ -537,7 +544,7 @@ void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint)
|
||||
|
||||
//Skin all children
|
||||
for (u32 j=0; j<joint->Children.size(); ++j)
|
||||
skinJoint(joint->Children[j], joint);
|
||||
skinJoint(joint->Children[j], joint, strength);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace scene
|
||||
virtual void animateMesh(f32 frame, f32 blend);
|
||||
|
||||
//! Preforms a software skin on this mesh based of joint positions
|
||||
virtual void skinMesh();
|
||||
virtual void skinMesh(f32 strength=1.f);
|
||||
|
||||
//! returns amount of mesh buffers.
|
||||
virtual u32 getMeshBufferCount() const;
|
||||
@@ -176,7 +176,7 @@ private:
|
||||
|
||||
void calculateGlobalMatrices(SJoint *Joint,SJoint *ParentJoint);
|
||||
|
||||
void skinJoint(SJoint *Joint, SJoint *ParentJoint);
|
||||
void skinJoint(SJoint *Joint, SJoint *ParentJoint, f32 strength=1.f);
|
||||
|
||||
void calculateTangents(core::vector3df& normal,
|
||||
core::vector3df& tangent, core::vector3df& binormal,
|
||||
|
||||
@@ -616,8 +616,8 @@ bool CIrrDeviceMacOSX::createWindow()
|
||||
|
||||
// we need to check where the exceptions may happen and work at them
|
||||
// for now we will just catch them to be able to avoid an app exit
|
||||
@try
|
||||
{
|
||||
//@try
|
||||
//{
|
||||
if (!CreationParams.Fullscreen)
|
||||
{
|
||||
if(!CreationParams.WindowId) //create another window when WindowId is null
|
||||
@@ -858,12 +858,12 @@ bool CIrrDeviceMacOSX::createWindow()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception)
|
||||
{
|
||||
closeDevice();
|
||||
result = false;
|
||||
}
|
||||
//}
|
||||
//@catch (NSException *exception)
|
||||
//{
|
||||
// closeDevice();
|
||||
// result = false;
|
||||
//}
|
||||
|
||||
if (result)
|
||||
{
|
||||
|
||||
@@ -101,6 +101,8 @@ src/karts/abstract_kart_animation.cpp
|
||||
src/karts/abstract_kart.cpp
|
||||
src/karts/cannon_animation.cpp
|
||||
src/karts/controller/ai_base_controller.cpp
|
||||
src/karts/controller/ai_base_lap_controller.cpp
|
||||
src/karts/controller/battle_ai.cpp
|
||||
src/karts/controller/ai_properties.cpp
|
||||
src/karts/controller/controller.cpp
|
||||
src/karts/controller/end_controller.cpp
|
||||
@@ -352,6 +354,8 @@ src/karts/abstract_kart_animation.hpp
|
||||
src/karts/abstract_kart.hpp
|
||||
src/karts/cannon_animation.hpp
|
||||
src/karts/controller/ai_base_controller.hpp
|
||||
src/karts/controller/ai_base_lap_controller.hpp
|
||||
src/karts/controller/battle_ai.hpp
|
||||
src/karts/controller/ai_properties.hpp
|
||||
src/karts/controller/controller.hpp
|
||||
src/karts/controller/end_controller.hpp
|
||||
|
||||
@@ -1139,7 +1139,7 @@ MATHJAX_RELPATH = http://www.mathjax.org/mathjax
|
||||
# typically be disabled. For large projects the javascript based search engine
|
||||
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
|
||||
|
||||
SEARCHENGINE = NO
|
||||
SEARCHENGINE = YES
|
||||
|
||||
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
||||
# implemented using a PHP enabled web server instead of at the web client
|
||||
|
||||
@@ -1202,7 +1202,7 @@ MATHJAX_EXTENSIONS =
|
||||
# typically be disabled. For large projects the javascript based search engine
|
||||
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
|
||||
|
||||
SEARCHENGINE = NO
|
||||
SEARCHENGINE = YES
|
||||
|
||||
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
||||
# implemented using a PHP enabled web server instead of at the web client
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "config/saved_grand_prix.hpp"
|
||||
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
@@ -145,10 +146,12 @@ void SavedGrandPrix::loadKarts(std::vector<RaceManager::KartStatus> & kart_list)
|
||||
int aikarts = 0;
|
||||
for(int i = 0; i < m_karts.size(); i++)
|
||||
{
|
||||
const KartProperties *kp = kart_properties_manager->getKart(m_karts[i].m_ident);
|
||||
|
||||
if(m_karts[i].m_local_player_id == -1)
|
||||
{
|
||||
//AI kart found
|
||||
kart_list[aikarts].m_ident = m_karts[i].m_ident;
|
||||
if(kp) kart_list[aikarts].m_ident = m_karts[i].m_ident;
|
||||
kart_list[aikarts].m_score = m_karts[i].m_score;
|
||||
kart_list[aikarts].m_overall_time = m_karts[i].m_overall_time;
|
||||
aikarts++;
|
||||
|
||||
@@ -994,9 +994,9 @@ void IrrDriver::removeTexture(video::ITexture *t)
|
||||
/** Adds an animated mesh to the scene.
|
||||
* \param mesh The animated mesh to add.
|
||||
*/
|
||||
scene::IAnimatedMeshSceneNode *IrrDriver::addAnimatedMesh(scene::IAnimatedMesh *mesh)
|
||||
scene::IAnimatedMeshSceneNode *IrrDriver::addAnimatedMesh(scene::IAnimatedMesh *mesh, scene::ISceneNode* parent)
|
||||
{
|
||||
return m_scene_manager->addAnimatedMeshSceneNode(mesh, NULL, -1,
|
||||
return m_scene_manager->addAnimatedMeshSceneNode(mesh, parent, -1,
|
||||
core::vector3df(0,0,0),
|
||||
core::vector3df(0,0,0),
|
||||
core::vector3df(1,1,1),
|
||||
|
||||
@@ -171,7 +171,7 @@ public:
|
||||
void removeMeshFromCache(scene::IMesh *mesh);
|
||||
void removeTexture(video::ITexture *t);
|
||||
scene::IAnimatedMeshSceneNode
|
||||
*addAnimatedMesh(scene::IAnimatedMesh *mesh);
|
||||
*addAnimatedMesh(scene::IAnimatedMesh *mesh, scene::ISceneNode* parent=NULL);
|
||||
scene::ICameraSceneNode
|
||||
*addCameraSceneNode();
|
||||
Camera *addCamera(unsigned int index, AbstractKart *kart);
|
||||
|
||||
@@ -778,7 +778,6 @@ void Material::install(bool is_full_path, bool complain_if_not_found)
|
||||
{
|
||||
fprintf(stderr, "Applying mask failed for '%s'!\n",
|
||||
m_texname.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_texture->grab();
|
||||
@@ -938,8 +937,9 @@ void Material::initParticlesEffect(const XMLNode *node)
|
||||
/** Adjusts the pitch of the given sfx depending on the given speed.
|
||||
* \param sfx The sound effect to adjust.
|
||||
* \param speed The speed of the kart.
|
||||
* \param should_be_paused Pause for other reasons, i.e. kart is rescued.
|
||||
*/
|
||||
void Material::setSFXSpeed(SFXBase *sfx, float speed) const
|
||||
void Material::setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) const
|
||||
{
|
||||
// Still make a sound when driving backwards on the material.
|
||||
if (speed < 0) speed = -speed;
|
||||
@@ -947,14 +947,14 @@ void Material::setSFXSpeed(SFXBase *sfx, float speed) const
|
||||
// If we paused it due to too low speed earlier, we can continue now.
|
||||
if (sfx->getStatus() == SFXManager::SFX_PAUSED)
|
||||
{
|
||||
if (speed<m_sfx_min_speed) return;
|
||||
if (speed<m_sfx_min_speed || should_be_paused == 1) return;
|
||||
// TODO: Do we first need to stop the sound completely so it
|
||||
// starts over?
|
||||
sfx->play();
|
||||
}
|
||||
else if (sfx->getStatus() == SFXManager::SFX_PLAYING)
|
||||
{
|
||||
if (speed<m_sfx_min_speed)
|
||||
if (speed<m_sfx_min_speed || should_be_paused == 1)
|
||||
{
|
||||
// Pausing it to differentiate with sounds that ended etc
|
||||
sfx->pause();
|
||||
|
||||
@@ -253,7 +253,7 @@ public:
|
||||
bool complain_if_not_found=true);
|
||||
~Material ();
|
||||
|
||||
void setSFXSpeed(SFXBase *sfx, float speed) const;
|
||||
void setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) const;
|
||||
void setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* mb);
|
||||
void adjustForFog(scene::ISceneNode* parent, video::SMaterial *m, bool use_fog) const;
|
||||
|
||||
|
||||
@@ -37,10 +37,20 @@ SkidMarks::SkidMarks(const AbstractKart& kart, float width) : m_kart(kart)
|
||||
{
|
||||
m_width = width;
|
||||
m_material = new video::SMaterial();
|
||||
m_material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
|
||||
m_material->MaterialType = video::EMT_ONETEXTURE_BLEND;
|
||||
m_material->MaterialTypeParam =
|
||||
pack_textureBlendFunc(video::EBF_SRC_ALPHA,
|
||||
video::EBF_ONE_MINUS_SRC_ALPHA,
|
||||
video::EMFN_MODULATE_1X,
|
||||
video::EAS_TEXTURE | video::EAS_VERTEX_COLOR);
|
||||
m_material->AmbientColor = video::SColor(128, 0, 0, 0);
|
||||
m_material->DiffuseColor = video::SColor(128, 16, 16, 16);
|
||||
//m_material->AmbientColor = video::SColor(255, 255, 255, 255);
|
||||
//m_material->DiffuseColor = video::SColor(255, 255, 255, 255);
|
||||
m_material->setFlag(video::EMF_ANISOTROPIC_FILTER, true);
|
||||
m_material->setFlag(video::EMF_ZWRITE_ENABLE, false);
|
||||
m_material->Shininess = 0;
|
||||
m_material->TextureLayer[0].Texture = irr_driver->getTexture("skidmarks.png");
|
||||
m_skid_marking = false;
|
||||
m_current = -1;
|
||||
} // SkidMark
|
||||
@@ -133,10 +143,19 @@ void SkidMarks::update(float dt, bool force_skid_marks,
|
||||
delta.normalize();
|
||||
delta *= m_width;
|
||||
|
||||
float distance = 0.0f;
|
||||
Vec3 start = m_left[m_current]->getCenterStart();
|
||||
Vec3 newPoint = (raycast_left.m_contactPointWS + raycast_right.m_contactPointWS)/2;
|
||||
// this linear distance does not account for the kart turning, it's true,
|
||||
// but it produces good enough results
|
||||
distance = (newPoint - start).length();
|
||||
|
||||
m_left [m_current]->add(raycast_left.m_contactPointWS,
|
||||
raycast_left.m_contactPointWS + delta);
|
||||
raycast_left.m_contactPointWS + delta,
|
||||
distance);
|
||||
m_right[m_current]->add(raycast_right.m_contactPointWS-delta,
|
||||
raycast_right.m_contactPointWS);
|
||||
raycast_right.m_contactPointWS,
|
||||
distance);
|
||||
// Adjust the boundary box of the mesh to include the
|
||||
// adjusted aabb of its buffers.
|
||||
core::aabbox3df aabb=m_nodes[m_current]->getMesh()
|
||||
@@ -219,6 +238,7 @@ SkidMarks::SkidMarkQuads::SkidMarkQuads(const Vec3 &left,
|
||||
video::SColor* custom_color)
|
||||
: scene::SMeshBuffer()
|
||||
{
|
||||
m_center_start = (left + right)/2;
|
||||
m_z_offset = z_offset;
|
||||
m_fade_out = 0.0f;
|
||||
|
||||
@@ -230,7 +250,7 @@ SkidMarks::SkidMarkQuads::SkidMarkQuads(const Vec3 &left,
|
||||
|
||||
Material = *material;
|
||||
m_aabb = core::aabbox3df(left.toIrrVector());
|
||||
add(left, right);
|
||||
add(left, right, 0.0f);
|
||||
|
||||
|
||||
} // SkidMarkQuads
|
||||
@@ -240,7 +260,8 @@ SkidMarks::SkidMarkQuads::SkidMarkQuads(const Vec3 &left,
|
||||
* \param left,right Left and right coordinates.
|
||||
*/
|
||||
void SkidMarks::SkidMarkQuads::add(const Vec3 &left,
|
||||
const Vec3 &right)
|
||||
const Vec3 &right,
|
||||
float distance)
|
||||
{
|
||||
// The skid marks must be raised slightly higher, otherwise it blends
|
||||
// too much with the track.
|
||||
@@ -248,13 +269,25 @@ void SkidMarks::SkidMarkQuads::add(const Vec3 &left,
|
||||
|
||||
video::S3DVertex v;
|
||||
v.Color = m_start_color;
|
||||
v.Color.setAlpha(m_start_alpha);
|
||||
v.Color.setAlpha(0); // initially create all vertices at alpha=0...
|
||||
|
||||
// then when adding a new set of vertices, make the previous 2 opaque.
|
||||
// this ensures that the last two vertices are always at alpha=0,
|
||||
// producing a fade-out effect
|
||||
if (n > 4)
|
||||
{
|
||||
Vertices[n - 1].Color.setAlpha(m_start_alpha);
|
||||
Vertices[n - 2].Color.setAlpha(m_start_alpha);
|
||||
}
|
||||
|
||||
v.Pos = left.toIrrVector();
|
||||
v.Pos.Y += m_z_offset;
|
||||
v.Normal = core::vector3df(0, 1, 0);
|
||||
v.TCoords = core::vector2df(0.0f, distance*0.5f);
|
||||
Vertices.push_back(v);
|
||||
v.Pos = right.toIrrVector();
|
||||
v.Pos.Y += m_z_offset;
|
||||
v.TCoords = core::vector2df(1.0f, distance*0.5f);
|
||||
Vertices.push_back(v);
|
||||
// Out of the box Irrlicht only supports triangle meshes and not
|
||||
// triangle strips. Since this is a strip it would be more efficient
|
||||
@@ -292,7 +325,8 @@ void SkidMarks::SkidMarkQuads::fade(float f)
|
||||
a -= (a < m_fade_out ? a : (int)m_fade_out);
|
||||
|
||||
c.setAlpha(a);
|
||||
for(unsigned int i=0; i<Vertices.size(); i++)
|
||||
// the first 2 and last 2 already have alpha=0 for fade-in and fade-out
|
||||
for(unsigned int i=2; i<Vertices.size() - 2; i++)
|
||||
{
|
||||
Vertices[i].Color.setAlpha(a);
|
||||
}
|
||||
|
||||
@@ -79,15 +79,20 @@ private:
|
||||
|
||||
video::SColor m_start_color;
|
||||
|
||||
/** Vector marking the start of the skidmarks (located between left and right wheel) */
|
||||
Vec3 m_center_start;
|
||||
|
||||
public:
|
||||
SkidMarkQuads (const Vec3 &left, const Vec3 &right,
|
||||
video::SMaterial *material, float z_offset,
|
||||
video::SColor* custom_color = NULL);
|
||||
void add (const Vec3 &left,
|
||||
const Vec3 &right);
|
||||
const Vec3 &right,
|
||||
float distance);
|
||||
void fade (float f);
|
||||
/** Returns the aabb of this skid mark quads. */
|
||||
const core::aabbox3df &getAABB() { return m_aabb; }
|
||||
const Vec3& getCenterStart() const { return m_center_start; }
|
||||
}; // SkidMarkQuads
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@@ -102,7 +107,7 @@ private:
|
||||
static float m_avoid_z_fighting;
|
||||
|
||||
public:
|
||||
SkidMarks(const AbstractKart& kart, float width=0.2f);
|
||||
SkidMarks(const AbstractKart& kart, float width=0.32f);
|
||||
~SkidMarks();
|
||||
void update (float dt, bool force_skid_marks=false,
|
||||
video::SColor* custom_color = NULL);
|
||||
|
||||
@@ -1017,10 +1017,12 @@ namespace GUIEngine
|
||||
// normal text will range from 0.2, in 640x* resolutions (won't scale
|
||||
// below that) to 0.4, in 1024x* resolutions, and linearly up
|
||||
const int screen_width = irr_driver->getFrameSize().Width;
|
||||
const float normal_text_scale =
|
||||
0.7f + 0.2f*std::max(0, screen_width - 640)/564.0f;
|
||||
const float title_text_scale =
|
||||
0.2f + 0.2f*std::max(0, screen_width - 640)/564.0f;
|
||||
const int screen_height = irr_driver->getFrameSize().Height;
|
||||
float scale = std::max(0, screen_width - 640)/564.0f;
|
||||
if (screen_height < 700) scale = std::min(scale, 0.25f); // attempt to compensate for small screens
|
||||
|
||||
float normal_text_scale = 0.7f + 0.2f*scale;
|
||||
float title_text_scale = 0.2f + 0.2f*scale;
|
||||
|
||||
ScalableFont* sfont =
|
||||
new ScalableFont(g_env,
|
||||
|
||||
@@ -38,7 +38,7 @@ ListWidget::ListWidget() : Widget(WTYPE_LIST)
|
||||
m_icons = NULL;
|
||||
m_listener = NULL;
|
||||
m_selected_column = NULL;
|
||||
m_sort_desc = true;
|
||||
m_sort_desc = false;
|
||||
m_sort_default = true;
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ void ListWidget::elementRemoved()
|
||||
}
|
||||
m_header_elements.clearAndDeleteAll();
|
||||
m_selected_column = NULL;
|
||||
m_sort_desc = true;
|
||||
m_sort_desc = false;
|
||||
m_sort_default = true;
|
||||
}
|
||||
|
||||
@@ -378,8 +378,8 @@ EventPropagation ListWidget::transmitEvent(Widget* w,
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sort_default = m_sort_desc && !m_sort_default;
|
||||
if (!m_sort_default) m_sort_desc = !m_sort_desc;
|
||||
m_sort_default = !m_sort_desc && !m_sort_default;
|
||||
}
|
||||
|
||||
m_sort_col = originator[(m_properties[PROP_ID] + "_column_").size()] - '0';
|
||||
|
||||
@@ -231,6 +231,7 @@
|
||||
<ClCompile Include="..\..\karts\cannon_animation.cpp" />
|
||||
<ClCompile Include="..\..\karts\controller\ai_base_controller.cpp" />
|
||||
<ClCompile Include="..\..\karts\controller\ai_properties.cpp" />
|
||||
<ClCompile Include="..\..\karts\controller\battle_ai.cpp" />
|
||||
<ClCompile Include="..\..\karts\controller\skidding_ai.cpp" />
|
||||
<ClCompile Include="..\..\karts\explosion_animation.cpp" />
|
||||
<ClCompile Include="..\..\karts\ghost_kart.cpp" />
|
||||
|
||||
@@ -35,12 +35,6 @@
|
||||
<Filter Include="Header Files\physics">
|
||||
<UniqueIdentifier>{1298df87-da0e-462e-b074-a496598571d8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\karts">
|
||||
<UniqueIdentifier>{11a7d573-5959-4be8-8a3f-d455d7833333}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\karts\controller">
|
||||
<UniqueIdentifier>{d477b64b-eb9c-4059-a647-98f3a2f7203a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\graphics">
|
||||
<UniqueIdentifier>{2f186570-85e9-4cea-88dc-0f716c6e141a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -154,6 +148,12 @@
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\items\karts">
|
||||
<UniqueIdentifier>{11a7d573-5959-4be8-8a3f-d455d7833333}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\items\karts\controller">
|
||||
<UniqueIdentifier>{d477b64b-eb9c-4059-a647-98f3a2f7203a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\main.cpp">
|
||||
@@ -885,6 +885,9 @@
|
||||
<ClCompile Include="..\..\karts\controller\ai_base_controller.cpp">
|
||||
<Filter>Source Files\karts\controller</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\karts\controller\battle_ai.cpp">
|
||||
<Filter>Source Files\karts\controller</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\main_loop.hpp">
|
||||
@@ -1158,34 +1161,34 @@
|
||||
<Filter>Header Files\physics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\kart.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\kart_control.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\kart_model.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\kart_properties.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\kart_properties_manager.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\max_speed.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\moveable.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\controller\controller.hpp">
|
||||
<Filter>Header Files\karts\controller</Filter>
|
||||
<Filter>Header Files\items\karts\controller</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\controller\end_controller.hpp">
|
||||
<Filter>Header Files\karts\controller</Filter>
|
||||
<Filter>Header Files\items\karts\controller</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\controller\player_controller.hpp">
|
||||
<Filter>Header Files\karts\controller</Filter>
|
||||
<Filter>Header Files\items\karts\controller</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\graphics\camera.hpp">
|
||||
<Filter>Header Files\graphics</Filter>
|
||||
@@ -1539,7 +1542,7 @@
|
||||
<Filter>Header Files\graphics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\kart_with_stats.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\tracks\track_sector.hpp">
|
||||
<Filter>Header Files\tracks</Filter>
|
||||
@@ -1575,7 +1578,7 @@
|
||||
<Filter>Header Files\states_screens</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\kart_gfx.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\states_screens\dialogs\select_challenge.hpp">
|
||||
<Filter>Header Files\states_screens\dialogs</Filter>
|
||||
@@ -1590,28 +1593,28 @@
|
||||
<Filter>Header Files\replay</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\ghost_kart.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\skidding.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\skidding_properties.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\explosion_animation.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\abstract_kart_animation.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\abstract_kart.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\cannon_animation.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\rescue_animation.hpp">
|
||||
<Filter>Header Files\karts</Filter>
|
||||
<Filter>Header Files\items\karts</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modes\demo_world.hpp">
|
||||
<Filter>Header Files\modes</Filter>
|
||||
@@ -1626,7 +1629,7 @@
|
||||
<Filter>Header Files\graphics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\controller\skidding_ai.hpp">
|
||||
<Filter>Header Files\karts\controller</Filter>
|
||||
<Filter>Header Files\items\karts\controller</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modes\cutscene_world.hpp">
|
||||
<Filter>Header Files\modes</Filter>
|
||||
@@ -1638,7 +1641,7 @@
|
||||
<Filter>Header Files\addons</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\controller\ai_properties.hpp">
|
||||
<Filter>Header Files\karts\controller</Filter>
|
||||
<Filter>Header Files\items\karts\controller</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\utils\interpolation_array.hpp">
|
||||
<Filter>Header Files\utils</Filter>
|
||||
@@ -1689,10 +1692,10 @@
|
||||
<Filter>Header Files\tracks</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\controller\ai_base_lap_controller.hpp">
|
||||
<Filter>Header Files\karts\controller</Filter>
|
||||
<Filter>Header Files\items\karts\controller</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\karts\controller\ai_base_controller.hpp">
|
||||
<Filter>Header Files\karts\controller</Filter>
|
||||
<Filter>Header Files\items\karts\controller</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -306,7 +306,8 @@ int WiimoteManager::askUserToConnectWiimotes()
|
||||
{
|
||||
new MessageDialog(
|
||||
_("Press the buttons 1+2 simultaneously on your wiimote to put "
|
||||
"it in discovery mode, then click on OK."),
|
||||
"it in discovery mode, then click on Yes."
|
||||
"Detailed instructions at supertuxkart.net/Wiimote"),
|
||||
MessageDialog::MESSAGE_DIALOG_CONFIRM,
|
||||
new WiimoteDialogListener(), true);
|
||||
|
||||
|
||||
@@ -329,9 +329,15 @@ void Attachment::hitBanana(Item *item, int new_attachment)
|
||||
void Attachment::handleCollisionWithKart(AbstractKart *other)
|
||||
{
|
||||
Attachment *attachment_other=other->getAttachment();
|
||||
|
||||
|
||||
if(getType()==Attachment::ATTACH_BOMB)
|
||||
{
|
||||
// Don't attach a bomb when the kart is shielded
|
||||
if(other->isShielded())
|
||||
{
|
||||
other->decreaseShieldTime();
|
||||
return;
|
||||
}
|
||||
// If both karts have a bomb, explode them immediately:
|
||||
if(attachment_other->getType()==Attachment::ATTACH_BOMB)
|
||||
{
|
||||
@@ -356,6 +362,12 @@ void Attachment::handleCollisionWithKart(AbstractKart *other)
|
||||
else if(attachment_other->getType()==Attachment::ATTACH_BOMB &&
|
||||
(attachment_other->getPreviousOwner()!=m_kart || World::getWorld()->getNumKarts() <= 2))
|
||||
{
|
||||
// Don't attach a bomb when the kart is shielded
|
||||
if(m_kart->isShielded())
|
||||
{
|
||||
m_kart->decreaseShieldTime();
|
||||
return;
|
||||
}
|
||||
set(ATTACH_BOMB, other->getAttachment()->getTimeLeft()+
|
||||
stk_config->m_bomb_time_increase, other);
|
||||
other->getAttachment()->clear();
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include "items/bowling.hpp"
|
||||
|
||||
#include "audio/sfx_base.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "graphics/hit_sfx.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
@@ -74,8 +76,22 @@ Bowling::Bowling(AbstractKart *kart)
|
||||
// should not live forever, auto-destruct after 20 seconds
|
||||
m_max_lifespan = 20;
|
||||
|
||||
m_roll_sfx = sfx_manager->createSoundSource("bowling_roll");
|
||||
m_roll_sfx->play();
|
||||
m_roll_sfx->setLoop(true);
|
||||
|
||||
} // Bowling
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Destructor, removes any playing sfx.
|
||||
*/
|
||||
Bowling::~Bowling()
|
||||
{
|
||||
if(m_roll_sfx->getStatus()==SFXManager::SFX_PLAYING)
|
||||
m_roll_sfx->stop();
|
||||
sfx_manager->deleteSFX(m_roll_sfx);
|
||||
} // ~RubberBall
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Initialises this object with data from the power.xml file.
|
||||
* \param node XML Node
|
||||
@@ -200,6 +216,10 @@ bool Bowling::updateAndDelete(float dt)
|
||||
hit(NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_roll_sfx->getStatus()==SFXManager::SFX_PLAYING)
|
||||
m_roll_sfx->position(getXYZ());
|
||||
|
||||
return false;
|
||||
} // updateAndDelete
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -237,5 +257,6 @@ HitEffect* Bowling::getHitEffect() const
|
||||
{
|
||||
if(m_has_hit_kart)
|
||||
return new HitSFX(getXYZ(), "strike");
|
||||
return NULL;
|
||||
else
|
||||
return new HitSFX(getXYZ(), "crash");
|
||||
} // getHitEffect
|
||||
|
||||
@@ -29,6 +29,7 @@ using namespace irr;
|
||||
#include "items/flyable.hpp"
|
||||
|
||||
class XMLNode;
|
||||
class SFXBase;
|
||||
|
||||
/**
|
||||
* \ingroup items
|
||||
@@ -45,8 +46,12 @@ private:
|
||||
* kart was hit. */
|
||||
bool m_has_hit_kart;
|
||||
|
||||
/** A sound effect for rolling ball. */
|
||||
SFXBase *m_roll_sfx;
|
||||
|
||||
public:
|
||||
Bowling(AbstractKart* kart);
|
||||
Bowling(AbstractKart* kart);
|
||||
virtual ~Bowling();
|
||||
static void init(const XMLNode &node, scene::IMesh *bowling);
|
||||
virtual bool updateAndDelete(float dt);
|
||||
virtual const core::stringw getHitString(const AbstractKart *kart) const;
|
||||
|
||||
@@ -515,4 +515,9 @@ HitEffect* Flyable::getHitEffect() const
|
||||
return new Explosion(getXYZ(), "explosion", "explosion_cake.xml");
|
||||
} // getHitEffect
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
unsigned int Flyable::getOwnerId()
|
||||
{
|
||||
return m_owner->getWorldKartId();
|
||||
}
|
||||
/* EOF */
|
||||
|
||||
@@ -208,6 +208,8 @@ public:
|
||||
* call, or if the inheriting object will update TerrainInfo itself
|
||||
* (or perhaps not at all if it is not needed). */
|
||||
void setDoTerrainInfo(bool d) { m_do_terrain_info = d; }
|
||||
// ------------------------------------------------------------------------
|
||||
unsigned int getOwnerId();
|
||||
}; // Flyable
|
||||
|
||||
#endif
|
||||
|
||||
@@ -152,7 +152,7 @@ void Powerup::set(PowerupManager::PowerupType type, int n)
|
||||
break ;
|
||||
|
||||
case PowerupManager::POWERUP_BOWLING:
|
||||
m_sound_use = sfx_manager->createSoundSource("bowling_roll");
|
||||
m_sound_use = sfx_manager->createSoundSource("bowling_shoot");
|
||||
break ;
|
||||
|
||||
case PowerupManager::POWERUP_ANVIL:
|
||||
@@ -264,7 +264,7 @@ void Powerup::use()
|
||||
Powerup::adjustSound();
|
||||
m_sound_use->play();
|
||||
|
||||
projectile_manager->newProjectile(m_owner, world->getTrack(), m_type);
|
||||
projectile_manager->newProjectile(m_owner, m_type);
|
||||
break ;
|
||||
|
||||
case PowerupManager::POWERUP_SWATTER:
|
||||
|
||||
@@ -156,8 +156,13 @@ void ProjectileManager::updateClient(float dt)
|
||||
} // for i in m_active_projectiles
|
||||
|
||||
} // updateClient
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
Flyable *ProjectileManager::newProjectile(AbstractKart *kart, Track* track,
|
||||
/** Creates a new projectile of the given type.
|
||||
* \param kart The kart which shoots the projectile.
|
||||
* \param type Type of projectile.
|
||||
*/
|
||||
Flyable *ProjectileManager::newProjectile(AbstractKart *kart,
|
||||
PowerupManager::PowerupType type)
|
||||
{
|
||||
Flyable *f;
|
||||
@@ -173,3 +178,22 @@ Flyable *ProjectileManager::newProjectile(AbstractKart *kart, Track* track,
|
||||
m_active_projectiles.push_back(f);
|
||||
return f;
|
||||
} // newProjectile
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Returns true if a projectile is within the given distance of the specified
|
||||
* kart.
|
||||
* \param kart The kart for which the test is done.
|
||||
* \param radius Distance within which the projectile must be.
|
||||
*/
|
||||
bool ProjectileManager::projectileIsClose(const AbstractKart * const kart,
|
||||
float radius)
|
||||
{
|
||||
float r2 = radius*radius;
|
||||
|
||||
for(Projectiles::iterator i = m_active_projectiles.begin();
|
||||
i != m_active_projectiles.end(); i++)
|
||||
{
|
||||
float dist2 = (*i)->getXYZ().distance2(kart->getXYZ());
|
||||
if(dist2<r2) return true;
|
||||
}
|
||||
return false;
|
||||
} // projectileIsClose
|
||||
@@ -61,10 +61,12 @@ public:
|
||||
void loadData ();
|
||||
void cleanup ();
|
||||
void update (float dt);
|
||||
Flyable* newProjectile (AbstractKart *kart, Track* track,
|
||||
Flyable* newProjectile (AbstractKart *kart,
|
||||
PowerupManager::PowerupType type);
|
||||
void Deactivate (Flyable *p) {}
|
||||
void removeTextures ();
|
||||
bool projectileIsClose(const AbstractKart * const kart,
|
||||
float radius);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds a special hit effect to be shown.
|
||||
* \param hit_effect The hit effect to be added. */
|
||||
|
||||
@@ -87,6 +87,10 @@ RubberBall::RubberBall(AbstractKart *kart)
|
||||
m_delete_timer = -1.0f;
|
||||
m_tunnel_count = 0;
|
||||
|
||||
LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
// FIXME: what does the rubber ball do in case of battle mode??
|
||||
if(!world) return;
|
||||
|
||||
computeTarget();
|
||||
|
||||
// initialises the current graph node
|
||||
@@ -141,8 +145,6 @@ void RubberBall::initializeControlPoints(const Vec3 &xyz)
|
||||
void RubberBall::computeTarget()
|
||||
{
|
||||
LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
// FIXME: what does the rubber ball do in case of battle mode??
|
||||
if(!world) return;
|
||||
|
||||
for(unsigned int p = race_manager->getFinishedKarts()+1;
|
||||
p < world->getNumKarts()+1; p++)
|
||||
@@ -190,13 +192,11 @@ unsigned int RubberBall::getSuccessorToHitTarget(unsigned int node_index,
|
||||
{
|
||||
int succ = 0;
|
||||
LinearWorld *lin_world = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
// FIXME: what does the rubber ball do in case of battle mode??
|
||||
if(lin_world)
|
||||
{
|
||||
unsigned int sect =
|
||||
lin_world->getSectorForKart(m_target);
|
||||
succ = QuadGraph::get()->getNode(node_index).getSuccessorToReach(sect);
|
||||
}
|
||||
|
||||
unsigned int sect =
|
||||
lin_world->getSectorForKart(m_target);
|
||||
succ = QuadGraph::get()->getNode(node_index).getSuccessorToReach(sect);
|
||||
|
||||
if(dist)
|
||||
*dist += QuadGraph::get()->getNode(node_index)
|
||||
.getDistanceToSuccessor(succ);
|
||||
@@ -322,6 +322,10 @@ const core::stringw RubberBall::getHitString(const AbstractKart *kart) const
|
||||
*/
|
||||
bool RubberBall::updateAndDelete(float dt)
|
||||
{
|
||||
LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
// FIXME: what does the rubber ball do in case of battle mode??
|
||||
if(!world) return true;
|
||||
|
||||
if(m_delete_timer>0)
|
||||
{
|
||||
m_delete_timer -= dt;
|
||||
@@ -629,7 +633,6 @@ float RubberBall::getMaxTerrainHeight(const Vec3 &vertical_offset) const
|
||||
void RubberBall::updateDistanceToTarget()
|
||||
{
|
||||
const LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
if(!world) return; // FIXME battle mode
|
||||
|
||||
float target_distance =
|
||||
world->getDistanceDownTrackForKart(m_target->getWorldKartId());
|
||||
|
||||
@@ -137,7 +137,7 @@ void RubberBand::updatePosition()
|
||||
*/
|
||||
void RubberBand::update(float dt)
|
||||
{
|
||||
if(m_owner->isEliminated() || m_owner->isShielded())
|
||||
if(m_owner->isEliminated())
|
||||
{
|
||||
// Rubber band snaps
|
||||
m_plunger->hit(NULL);
|
||||
|
||||
@@ -55,6 +55,7 @@ AbstractKart::AbstractKart(const std::string& ident,
|
||||
m_kart_length = m_kart_model->getLength();
|
||||
m_wheel_graphics_position = m_kart_model->getWheelsGraphicsPosition();
|
||||
m_nitro_emitter_position = m_kart_model->getNitroEmittersPositon();
|
||||
m_has_nitro_emitter = m_kart_model->hasNitroEmitters();
|
||||
} // AbstractKart
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -55,6 +55,8 @@ private:
|
||||
const Vec3* m_wheel_graphics_position;
|
||||
/** The position of all nitro emitters in the 3d model */
|
||||
const Vec3* m_nitro_emitter_position;
|
||||
/** True if kart has nitro emitters */
|
||||
bool m_has_nitro_emitter;
|
||||
|
||||
/** Index of kart in world. */
|
||||
unsigned int m_world_kart_id;
|
||||
@@ -161,6 +163,10 @@ public:
|
||||
/** Returns the position of a nitro emitter relative to the kart */
|
||||
const Vec3& getNitroEmitterPosition(int i) const
|
||||
{assert(i>=0 && i<2); return m_nitro_emitter_position[i];}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if kart has nitro emitters */
|
||||
const bool hasNitroEmitter() const
|
||||
{return m_has_nitro_emitter;}
|
||||
|
||||
// ========================================================================
|
||||
// Emergency animation related functions.
|
||||
|
||||
@@ -157,6 +157,7 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
|
||||
m_engine_sound = sfx_manager->createSoundSource(m_kart_properties->getEngineSfxType());
|
||||
m_beep_sound = sfx_manager->createSoundSource( "horn" );
|
||||
m_crash_sound = sfx_manager->createSoundSource( "crash" );
|
||||
m_boing_sound = sfx_manager->createSoundSource( "boing" );
|
||||
m_goo_sound = sfx_manager->createSoundSource( "goo" );
|
||||
m_skid_sound = sfx_manager->createSoundSource( "skid" );
|
||||
m_terrain_sound = NULL;
|
||||
@@ -181,6 +182,7 @@ void Kart::init(RaceManager::KartType type)
|
||||
m_goo_sound->volume( 1.0f / factor );
|
||||
m_skid_sound->volume( 1.0f / factor );
|
||||
m_crash_sound->volume( 1.0f / factor );
|
||||
m_boing_sound->volume( 1.0f / factor );
|
||||
m_beep_sound->volume( 1.0f / factor );
|
||||
}
|
||||
else
|
||||
@@ -189,6 +191,7 @@ void Kart::init(RaceManager::KartType type)
|
||||
m_skid_sound->volume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_crash_sound->volume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_beep_sound->volume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_boing_sound->volume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,6 +247,7 @@ Kart::~Kart()
|
||||
sfx_manager->deleteSFX(m_skid_sound );
|
||||
sfx_manager->deleteSFX(m_goo_sound );
|
||||
sfx_manager->deleteSFX(m_beep_sound );
|
||||
sfx_manager->deleteSFX(m_boing_sound );
|
||||
delete m_kart_gfx;
|
||||
if(m_terrain_sound) sfx_manager->deleteSFX(m_terrain_sound);
|
||||
if(m_previous_terrain_sound) sfx_manager->deleteSFX(m_previous_terrain_sound);
|
||||
@@ -1032,6 +1036,7 @@ void Kart::eliminate()
|
||||
m_stars_effect->update(1);
|
||||
}
|
||||
|
||||
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_TERRAIN, 0);
|
||||
m_eliminated = true;
|
||||
|
||||
m_node->setVisible(false);
|
||||
@@ -1171,6 +1176,7 @@ void Kart::update(float dt)
|
||||
m_engine_sound->position ( getXYZ() );
|
||||
m_crash_sound->position ( getXYZ() );
|
||||
m_skid_sound->position ( getXYZ() );
|
||||
m_boing_sound->position ( getXYZ() );
|
||||
|
||||
// Check if a kart is (nearly) upside down and not moving much --> automatic rescue
|
||||
if(World::getWorld()->getTrack()->isAutoRescueEnabled() &&
|
||||
@@ -1405,6 +1411,7 @@ void Kart::handleMaterialSFX(const Material *material)
|
||||
m_terrain_sound = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_previous_terrain_sound &&
|
||||
m_previous_terrain_sound->getStatus()==SFXManager::SFX_STOPPED)
|
||||
{
|
||||
@@ -1414,15 +1421,19 @@ void Kart::handleMaterialSFX(const Material *material)
|
||||
sfx_manager->deleteSFX(m_previous_terrain_sound);
|
||||
m_previous_terrain_sound = NULL;
|
||||
}
|
||||
|
||||
bool m_schedule_pause = m_flying ||
|
||||
dynamic_cast<RescueAnimation*>(getKartAnimation()) ||
|
||||
dynamic_cast<ExplosionAnimation*>(getKartAnimation());
|
||||
|
||||
// terrain sound is not necessarily a looping sound so check its status before
|
||||
// setting its speed, to avoid 'ressuscitating' sounds that had already stopped
|
||||
if(m_terrain_sound
|
||||
&& (m_terrain_sound->getStatus() == SFXManager::SFX_PLAYING
|
||||
|| m_terrain_sound->getStatus() == SFXManager::SFX_PAUSED))
|
||||
if(m_terrain_sound &&
|
||||
(m_terrain_sound->getStatus()==SFXManager::SFX_PLAYING ||
|
||||
m_terrain_sound->getStatus()==SFXManager::SFX_PAUSED))
|
||||
{
|
||||
m_terrain_sound->position(getXYZ());
|
||||
material->setSFXSpeed(m_terrain_sound, m_speed);
|
||||
material->setSFXSpeed(m_terrain_sound, m_speed, m_schedule_pause);
|
||||
}
|
||||
|
||||
} // handleMaterialSFX
|
||||
@@ -1668,7 +1679,7 @@ void Kart::crashed(AbstractKart *k, bool update_attachments)
|
||||
getAttachment()->handleCollisionWithKart(k);
|
||||
}
|
||||
m_controller->crashed(k);
|
||||
crashed();
|
||||
crashed(NULL, k);
|
||||
} // crashed(Kart, update_attachments
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -1808,13 +1819,15 @@ void Kart::crashed(const Material *m, const Vec3 &normal)
|
||||
} // if(m && m->getCollisionReaction() != Material::NORMAL &&
|
||||
// !getKartAnimation())
|
||||
m_controller->crashed(m);
|
||||
crashed();
|
||||
crashed(m, NULL);
|
||||
} // crashed(Material)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Common code used when a kart or a material was hit.
|
||||
* @param m The material collided into, or NULL if none
|
||||
* @param k The kart collided into, or NULL if none
|
||||
*/
|
||||
void Kart::crashed()
|
||||
void Kart::crashed(const Material* m, AbstractKart *k)
|
||||
{
|
||||
if(World::getWorld()->getTime()-m_time_last_crash < 0.5f) return;
|
||||
|
||||
@@ -1828,8 +1841,16 @@ void Kart::crashed()
|
||||
{
|
||||
// In case that the sfx is longer than 0.5 seconds, only play it if
|
||||
// it's not already playing.
|
||||
if(m_crash_sound->getStatus() != SFXManager::SFX_PLAYING)
|
||||
m_crash_sound->play();
|
||||
if (isShielded() || (k != NULL && k->isShielded()))
|
||||
{
|
||||
if (m_boing_sound->getStatus() != SFXManager::SFX_PLAYING)
|
||||
m_boing_sound->play();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_crash_sound->getStatus() != SFXManager::SFX_PLAYING)
|
||||
m_crash_sound->play();
|
||||
}
|
||||
}
|
||||
|
||||
m_bounce_back_time = 0.1f;
|
||||
@@ -2368,7 +2389,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
|
||||
wheel_up_axis[i] = m_default_suspension_length[i]
|
||||
- m_vehicle->getWheelInfo(i).m_raycastInfo.m_suspensionLength;
|
||||
}
|
||||
m_kart_model->update(m_wheel_rotation_dt, getSteerPercent(), wheel_up_axis);
|
||||
m_kart_model->update(m_wheel_rotation_dt, getSteerPercent(), wheel_up_axis, m_speed);
|
||||
|
||||
Vec3 center_shift = m_kart_properties->getGravityCenterShift();
|
||||
float y = m_vehicle->getWheelInfo(0).m_chassisConnectionPointCS.getY()
|
||||
|
||||
@@ -130,7 +130,7 @@ private:
|
||||
/** Current leaning of the kart. */
|
||||
float m_current_lean;
|
||||
|
||||
/** If > 0 then bubble gum effect is on */
|
||||
/** If > 0 then bubble gum effect is on. This is the sliding when hitting a gum on the floor, not the shield. */
|
||||
float m_bubblegum_time;
|
||||
|
||||
/** The torque to apply after hitting a bubble gum. */
|
||||
@@ -211,6 +211,7 @@ private:
|
||||
SFXBase *m_previous_terrain_sound;
|
||||
SFXBase *m_skid_sound;
|
||||
SFXBase *m_goo_sound;
|
||||
SFXBase *m_boing_sound;
|
||||
float m_time_last_crash;
|
||||
|
||||
/** To prevent using nitro in too short bursts */
|
||||
@@ -225,7 +226,7 @@ private:
|
||||
void updateEngineSFX();
|
||||
void updateNitro(float dt);
|
||||
float getActualWheelForce();
|
||||
void crashed();
|
||||
void crashed(const Material* m, AbstractKart *k);
|
||||
void loadData(RaceManager::KartType type, bool animatedModel);
|
||||
|
||||
public:
|
||||
|
||||
@@ -50,13 +50,16 @@ KartGFX::KartGFX(const AbstractKart *kart)
|
||||
|
||||
|
||||
*/
|
||||
Vec3 rear_left(kart->getWheelGraphicsPosition(3).toIrrVector().X, (kart->getKartHeight()-0.6f)*0.35f,
|
||||
kart->getWheelGraphicsPosition(3).toIrrVector().Z);
|
||||
Vec3 rear_right(kart->getWheelGraphicsPosition(2).toIrrVector().X, (kart->getKartHeight()-0.6f)*0.35f,
|
||||
kart->getWheelGraphicsPosition(2).toIrrVector().Z);
|
||||
Vec3 rear_left(kart->getWheelGraphicsPosition(3).toIrrVector().X, 0.05f,
|
||||
kart->getWheelGraphicsPosition(3).toIrrVector().Z-0.1f);
|
||||
Vec3 rear_right(kart->getWheelGraphicsPosition(2).toIrrVector().X, 0.05f,
|
||||
kart->getWheelGraphicsPosition(2).toIrrVector().Z-0.1f);
|
||||
|
||||
Vec3 rear_center(0, kart->getKartHeight()*0.35f,
|
||||
-kart->getKartLength()*0.35f);
|
||||
|
||||
Vec3 rear_nitro_center(0, kart->getKartHeight()*0.2f,
|
||||
-kart->getKartLength()*0.1f);
|
||||
|
||||
// FIXME Used to match the emitter as seen in blender
|
||||
const float delta = 0.6f;
|
||||
@@ -67,6 +70,8 @@ KartGFX::KartGFX(const AbstractKart *kart)
|
||||
Vec3 rear_nitro_left(kart->getNitroEmitterPosition(1).toIrrVector().X,
|
||||
kart->getNitroEmitterPosition(1).toIrrVector().Y,
|
||||
kart->getNitroEmitterPosition(1).toIrrVector().Z + delta);
|
||||
if (!kart->hasNitroEmitter())
|
||||
rear_nitro_right = rear_nitro_left = rear_nitro_center;
|
||||
|
||||
// Create all effects. Note that they must be created
|
||||
// in the order of KartGFXType.
|
||||
|
||||
@@ -89,6 +89,7 @@ KartModel::KartModel(bool is_master)
|
||||
m_wheel_filename[1] = "";
|
||||
m_wheel_filename[2] = "";
|
||||
m_wheel_filename[3] = "";
|
||||
m_speed_weighted_objects.clear();
|
||||
m_animated_node = NULL;
|
||||
m_mesh = NULL;
|
||||
for(unsigned int i=AF_BEGIN; i<=AF_END; i++)
|
||||
@@ -123,6 +124,8 @@ void KartModel::loadInfo(const XMLNode &node)
|
||||
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("start-speed-weighted", &m_animation_frame[AF_SPEED_WEIGHTED_START] );
|
||||
animation_node->get("end-speed-weighted", &m_animation_frame[AF_SPEED_WEIGHTED_END] );
|
||||
animation_node->get("speed", &m_animation_speed );
|
||||
}
|
||||
|
||||
@@ -135,13 +138,22 @@ void KartModel::loadInfo(const XMLNode &node)
|
||||
}
|
||||
|
||||
m_nitro_emitter_position[0] = Vec3 (0,0.1f,0);
|
||||
|
||||
m_nitro_emitter_position[1] = Vec3 (0,0.1f,0);
|
||||
m_has_nitro_emitter = false;
|
||||
|
||||
if(const XMLNode *nitroEmitter_node=node.getNode("nitro-emitter"))
|
||||
{
|
||||
loadNitroEmitterInfo(*nitroEmitter_node, "nitro-emitter-a", 0);
|
||||
loadNitroEmitterInfo(*nitroEmitter_node, "nitro-emitter-b", 1);
|
||||
m_has_nitro_emitter = true;
|
||||
}
|
||||
|
||||
if(const XMLNode *speedWeighted_node=node.getNode("speed-weighted"))
|
||||
{
|
||||
for(unsigned int i=0 ; i < speedWeighted_node->getNumNodes() ; i++)
|
||||
{
|
||||
loadSpeedWeightedInfo(speedWeighted_node->getNode(i));
|
||||
}
|
||||
}
|
||||
|
||||
if(const XMLNode *hat_node=node.getNode("hat"))
|
||||
@@ -184,6 +196,22 @@ KartModel::~KartModel()
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i=0; i<m_speed_weighted_objects.size(); i++)
|
||||
{
|
||||
if(m_speed_weighted_objects[i].m_node)
|
||||
{
|
||||
// Master KartModels should never have a speed weighted object attached.
|
||||
assert(!m_is_master);
|
||||
|
||||
m_speed_weighted_objects[i].m_node->drop();
|
||||
}
|
||||
if(m_is_master && m_speed_weighted_objects[i].m_model)
|
||||
{
|
||||
irr_driver->dropAllTextures(m_speed_weighted_objects[i].m_model);
|
||||
irr_driver->removeMeshFromCache(m_speed_weighted_objects[i].m_model);
|
||||
}
|
||||
}
|
||||
|
||||
if(m_is_master && m_mesh)
|
||||
{
|
||||
m_mesh->drop();
|
||||
@@ -231,6 +259,7 @@ KartModel* KartModel::makeCopy()
|
||||
|
||||
km->m_nitro_emitter_position[0] = m_nitro_emitter_position[0];
|
||||
km->m_nitro_emitter_position[1] = m_nitro_emitter_position[1];
|
||||
km->m_has_nitro_emitter = m_has_nitro_emitter;
|
||||
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
@@ -245,6 +274,17 @@ KartModel* KartModel::makeCopy()
|
||||
km->m_max_suspension[i] = m_max_suspension[i];
|
||||
km->m_dampen_suspension_amplitude[i]= m_dampen_suspension_amplitude[i];
|
||||
}
|
||||
|
||||
km->m_speed_weighted_objects.resize(m_speed_weighted_objects.size());
|
||||
for(size_t i=0; i<m_speed_weighted_objects.size(); i++)
|
||||
{
|
||||
km->m_speed_weighted_objects[i].m_model = m_speed_weighted_objects[i].m_model;
|
||||
// Master should not have any speed weighted nodes.
|
||||
assert(!m_speed_weighted_objects[i].m_node);
|
||||
km->m_speed_weighted_objects[i].m_name = m_speed_weighted_objects[i].m_name;
|
||||
km->m_speed_weighted_objects[i].m_position = m_speed_weighted_objects[i].m_position;
|
||||
}
|
||||
|
||||
for(unsigned int i=AF_BEGIN; i<=AF_END; i++)
|
||||
km->m_animation_frame[i] = m_animation_frame[i];
|
||||
|
||||
@@ -297,6 +337,13 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models)
|
||||
if(!m_wheel_model[i]) continue;
|
||||
m_wheel_node[i]->setParent(lod_node);
|
||||
}
|
||||
|
||||
// Become the owner of the speed weighted objects
|
||||
for(size_t i=0; i<m_speed_weighted_objects.size(); i++)
|
||||
{
|
||||
if(!m_speed_weighted_objects[i].m_node) continue;
|
||||
m_speed_weighted_objects[i].m_node->setParent(lod_node);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -314,6 +361,8 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models)
|
||||
std::string debug_name = m_model_filename+" (kart-model)";
|
||||
node->setName(debug_name.c_str());
|
||||
#endif
|
||||
|
||||
// Attach the wheels
|
||||
for(unsigned int i=0; i<4; i++)
|
||||
{
|
||||
if(!m_wheel_model[i]) continue;
|
||||
@@ -325,6 +374,27 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models)
|
||||
#endif
|
||||
m_wheel_node[i]->setPosition(m_wheel_graphics_position[i].toIrrVector());
|
||||
}
|
||||
|
||||
// Attach the speed weighted objects + set the animation state
|
||||
for(size_t i=0 ; i < m_speed_weighted_objects.size() ; i++)
|
||||
{
|
||||
SpeedWeightedObject& obj = m_speed_weighted_objects[i];
|
||||
obj.m_node = NULL;
|
||||
if(obj.m_model)
|
||||
{
|
||||
obj.m_node = irr_driver->addAnimatedMesh(obj.m_model, node);
|
||||
obj.m_node->grab();
|
||||
|
||||
obj.m_node->setAnimationStrength(0.0f);
|
||||
obj.m_node->setFrameLoop(m_animation_frame[AF_SPEED_WEIGHTED_START], m_animation_frame[AF_SPEED_WEIGHTED_END]);
|
||||
|
||||
#ifdef DEBUG
|
||||
std::string debug_name = obj.m_name+" (speed-weighted)";
|
||||
obj.m_node->setName(debug_name.c_str());
|
||||
#endif
|
||||
obj.m_node->setPosition(obj.m_position.toIrrVector());
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
} // attachModel
|
||||
@@ -348,10 +418,31 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
|
||||
m_mesh->grab();
|
||||
irr_driver->grabAllTextures(m_mesh);
|
||||
|
||||
Vec3 min, max;
|
||||
MeshTools::minMax3D(m_mesh->getMesh(m_animation_frame[AF_STRAIGHT]), &min, &max);
|
||||
Vec3 kart_min, kart_max;
|
||||
MeshTools::minMax3D(m_mesh->getMesh(m_animation_frame[AF_STRAIGHT]), &kart_min, &kart_max);
|
||||
|
||||
Vec3 size = max-min;
|
||||
// Load the speed weighted object models. We need to do that now because it can affect the dimensions of the kart
|
||||
for(size_t i=0 ; i < m_speed_weighted_objects.size() ; i++)
|
||||
{
|
||||
SpeedWeightedObject& obj = m_speed_weighted_objects[i];
|
||||
std::string full_name =
|
||||
kart_properties.getKartDir()+obj.m_name;
|
||||
obj.m_model = irr_driver->getAnimatedMesh(full_name);
|
||||
// Grab all textures. This is done for the master only, so
|
||||
// the destructor will only free the textures if a master
|
||||
// copy is freed.
|
||||
irr_driver->grabAllTextures(obj.m_model);
|
||||
|
||||
// Update min/max
|
||||
Vec3 obj_min, obj_max;
|
||||
MeshTools::minMax3D(obj.m_model, &obj_min, &obj_max);
|
||||
obj_min += obj.m_position;
|
||||
obj_max += obj.m_position;
|
||||
kart_min.min(obj_min);
|
||||
kart_max.min(obj_max);
|
||||
}
|
||||
|
||||
Vec3 size = kart_max-kart_min;
|
||||
m_kart_width = size.getX();
|
||||
m_kart_height = size.getY();
|
||||
m_kart_length = size.getZ();
|
||||
@@ -416,6 +507,18 @@ void KartModel::loadNitroEmitterInfo(const XMLNode &node,
|
||||
emitter_node->get("position", &m_nitro_emitter_position[index]);
|
||||
} // loadNitroEmitterInfo
|
||||
|
||||
/** Loads a single speed weighted node. */
|
||||
void KartModel::loadSpeedWeightedInfo(const XMLNode* speed_weighted_node)
|
||||
{
|
||||
SpeedWeightedObject obj;
|
||||
|
||||
speed_weighted_node->get("position", &obj.m_position);
|
||||
speed_weighted_node->get("model", &obj.m_name);
|
||||
|
||||
if(!obj.m_name.empty())
|
||||
m_speed_weighted_objects.push_back(obj);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Loads a single wheel node. Currently this is the name of the wheel model
|
||||
* and the position of the wheel relative to the kart.
|
||||
@@ -486,7 +589,7 @@ void KartModel::reset()
|
||||
{
|
||||
// Reset the wheels
|
||||
const float suspension[4]={0,0,0,0};
|
||||
update(0, 0.0f, suspension);
|
||||
update(0, 0.0f, suspension, 0.0f);
|
||||
|
||||
// Stop any animations currently being played.
|
||||
setAnimation(KartModel::AF_DEFAULT);
|
||||
@@ -592,12 +695,14 @@ void KartModel::OnAnimationEnd(scene::IAnimatedMeshSceneNode *node)
|
||||
} // OnAnimationEnd
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Rotates and turns the wheels appropriately, and adjust for suspension.
|
||||
/** Rotates and turns the wheels appropriately, and adjust for suspension
|
||||
+ updates the speed-weighted objects' animations.
|
||||
* \param rotation_dt How far the wheels have rotated since last time.
|
||||
* \param steer The actual steer settings.
|
||||
* \param suspension Suspension height for all four wheels.
|
||||
* \param speed The speed of the kart in meters/sec, used for the speed-weighted objects' animations
|
||||
*/
|
||||
void KartModel::update(float rotation_dt, float steer, const float suspension[4])
|
||||
void KartModel::update(float rotation_dt, float steer, const float suspension[4], float speed)
|
||||
{
|
||||
float clamped_suspension[4];
|
||||
// Clamp suspension to minimum and maximum suspension length, so that
|
||||
@@ -653,6 +758,18 @@ void KartModel::update(float rotation_dt, float steer, const float suspension[4]
|
||||
// If animations are disabled, stop here
|
||||
if (m_animated_node == NULL) return;
|
||||
|
||||
// Update the speed-weighted objects' animations
|
||||
for(size_t i=0 ; i < m_speed_weighted_objects.size() ; i++)
|
||||
{
|
||||
SpeedWeightedObject& obj = m_speed_weighted_objects[i];
|
||||
float strength = speed * m_kart->getKartProperties()->getSpeedWeightedStrengthFactor();
|
||||
btClamp<float>(strength, 0.0f, 1.0f);
|
||||
obj.m_node->setAnimationStrength(strength);
|
||||
|
||||
float anim_speed = speed * m_kart->getKartProperties()->getSpeedWeightedSpeedFactor();
|
||||
obj.m_node->setAnimationSpeed(anim_speed);
|
||||
}
|
||||
|
||||
// Check if the end animation is being played, if so, don't
|
||||
// play steering animation.
|
||||
if(m_current_animation!=AF_DEFAULT) return;
|
||||
@@ -708,4 +825,3 @@ void KartModel::attachHat(){
|
||||
} // if bone
|
||||
} // if(m_hat_name)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define HEADER_KART_MODEL_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <IAnimatedMeshSceneNode.h>
|
||||
namespace irr
|
||||
@@ -36,6 +37,23 @@ class AbstractKart;
|
||||
class KartProperties;
|
||||
class XMLNode;
|
||||
|
||||
struct SpeedWeightedObject
|
||||
{
|
||||
SpeedWeightedObject() : m_model(NULL), m_node(NULL), m_position(), m_name() {}
|
||||
/** Model */
|
||||
scene::IAnimatedMesh * m_model;
|
||||
|
||||
/** The scene node the speed weighted model is attached to */
|
||||
scene::IAnimatedMeshSceneNode * m_node;
|
||||
|
||||
/** The position of the "speed weighted" objects relative to the kart */
|
||||
Vec3 m_position;
|
||||
|
||||
/** Filename of the "speed weighted" object */
|
||||
std::string m_name;
|
||||
};
|
||||
typedef std::vector<SpeedWeightedObject> SpeedWeightedObjectList;
|
||||
|
||||
/**
|
||||
* \brief This class stores a 3D kart model.
|
||||
* It takes especially care of attaching
|
||||
@@ -66,7 +84,9 @@ public:
|
||||
AF_WIN_START, // Begin of win animation
|
||||
AF_WIN_LOOP_START, // Begin of win loop animation
|
||||
AF_WIN_END, // End of win animation
|
||||
AF_END=AF_WIN_END, // Last animation frame
|
||||
AF_SPEED_WEIGHTED_START, // Start of speed-weighted animation
|
||||
AF_SPEED_WEIGHTED_END, // End of speed-weighted animation
|
||||
AF_END=AF_SPEED_WEIGHTED_END, // Last animation frame
|
||||
AF_COUNT}; // Number of entries here
|
||||
private:
|
||||
/** Which frame number starts/end which animation. */
|
||||
@@ -120,6 +140,12 @@ private:
|
||||
/** The position of the nitro emitters */
|
||||
Vec3 m_nitro_emitter_position[2];
|
||||
|
||||
/** True if kart has nitro emitters */
|
||||
bool m_has_nitro_emitter;
|
||||
|
||||
/** The speed weighted objects. */
|
||||
SpeedWeightedObjectList m_speed_weighted_objects;
|
||||
|
||||
/** Minimum suspension length. If the displayed suspension is
|
||||
* shorter than this, the wheel would look wrong. */
|
||||
float m_min_suspension[4];
|
||||
@@ -151,6 +177,8 @@ private:
|
||||
void loadNitroEmitterInfo(const XMLNode &node,
|
||||
const std::string &emitter_name, int index);
|
||||
|
||||
void loadSpeedWeightedInfo(const XMLNode* speed_weighted_node);
|
||||
|
||||
void OnAnimationEnd(scene::IAnimatedMeshSceneNode *node);
|
||||
|
||||
/** Pointer to the kart object belonging to this kart model. */
|
||||
@@ -164,7 +192,7 @@ public:
|
||||
void loadInfo(const XMLNode &node);
|
||||
bool loadModels(const KartProperties &kart_properties);
|
||||
void update(float rotation_dt, float steer,
|
||||
const float suspension[4]);
|
||||
const float suspension[4], float speed);
|
||||
void setDefaultPhysicsPosition(const Vec3 ¢er_shift,
|
||||
float wheel_radius);
|
||||
void finishedRace();
|
||||
@@ -214,6 +242,19 @@ public:
|
||||
const Vec3* getNitroEmittersPositon() const
|
||||
{return m_nitro_emitter_position;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if kart has nitro emitters */
|
||||
const bool hasNitroEmitters() const
|
||||
{return m_has_nitro_emitter;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the number of speed weighted objects for this kart */
|
||||
size_t getSpeedWeightedObjectsCount() const
|
||||
{return m_speed_weighted_objects.size();}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the position of a speed weighted object relative to the kart.
|
||||
* \param i Index of the object */
|
||||
const SpeedWeightedObject& getSpeedWeightedObject(int i) const
|
||||
{return m_speed_weighted_objects[i];}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the length of the kart model. */
|
||||
float getLength () const {return m_kart_length; }
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -68,7 +68,8 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
m_nitro_max_speed_increase = m_nitro_duration = m_nitro_fade_out_time =
|
||||
m_suspension_stiffness = m_wheel_damping_relaxation = m_wheel_base =
|
||||
m_wheel_damping_compression = m_friction_slip = m_roll_influence =
|
||||
m_wheel_radius = m_chassis_linear_damping = m_max_suspension_force =
|
||||
m_wheel_radius = m_speed_weighted_strength_factor = m_speed_weighted_speed_factor =
|
||||
m_chassis_linear_damping = m_max_suspension_force =
|
||||
m_chassis_angular_damping = m_suspension_rest =
|
||||
m_max_speed_reverse_ratio = m_rescue_vert_offset =
|
||||
m_upright_tolerance = m_collision_terrain_impulse =
|
||||
@@ -426,6 +427,12 @@ void KartProperties::getAllData(const XMLNode * root)
|
||||
wheels_node->get("radius", &m_wheel_radius );
|
||||
}
|
||||
|
||||
if(const XMLNode *speed_weighted_node = root->getNode("speed-weighted"))
|
||||
{
|
||||
speed_weighted_node->get("strength-factor", &m_speed_weighted_strength_factor);
|
||||
speed_weighted_node->get("speed-factor", &m_speed_weighted_speed_factor);
|
||||
}
|
||||
|
||||
if(const XMLNode *friction_node = root->getNode("friction"))
|
||||
friction_node->get("slip", &m_friction_slip);
|
||||
|
||||
@@ -626,6 +633,8 @@ void KartProperties::checkAllSet(const std::string &filename)
|
||||
CHECK_NEG(m_time_reset_steer, "turn time-reset-steer" );
|
||||
CHECK_NEG(m_wheel_damping_relaxation, "wheels damping-relaxation" );
|
||||
CHECK_NEG(m_wheel_damping_compression, "wheels damping-compression" );
|
||||
CHECK_NEG(m_speed_weighted_strength_factor, "speed-weighted strength-factor" );
|
||||
CHECK_NEG(m_speed_weighted_speed_factor, "speed-weighted speed-factor" );
|
||||
CHECK_NEG(m_wheel_radius, "wheels radius" );
|
||||
CHECK_NEG(m_friction_slip, "friction slip" );
|
||||
CHECK_NEG(m_roll_influence, "stability roll-influence" );
|
||||
|
||||
@@ -264,6 +264,10 @@ private:
|
||||
float m_roll_influence;
|
||||
float m_wheel_radius;
|
||||
|
||||
// Parameters for speed-weighted objects
|
||||
float m_speed_weighted_strength_factor;
|
||||
float m_speed_weighted_speed_factor;
|
||||
|
||||
/** An impulse pushing the kart down which is proportional to speed. So
|
||||
* the actual impulse is speed * m_downward_impulse_factor. Set it to
|
||||
* 0 to disable completely. Based on
|
||||
@@ -528,6 +532,14 @@ public:
|
||||
/** Returns wheel radius. */
|
||||
float getWheelRadius () const {return m_wheel_radius; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns animation strength factor for speed-weighted objects */
|
||||
float getSpeedWeightedStrengthFactor() const {return m_speed_weighted_strength_factor;}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns animation speed factor for speed-weighted objects */
|
||||
float getSpeedWeightedSpeedFactor() const {return m_speed_weighted_speed_factor;}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the wheel base (distance front to rear axis). */
|
||||
float getWheelBase () const {return m_wheel_base; }
|
||||
|
||||
@@ -53,6 +53,8 @@ void SoccerWorld::init()
|
||||
{
|
||||
WorldWithRank::init();
|
||||
m_display_rank = false;
|
||||
m_goal_timer = 0.f;
|
||||
m_lastKartToHitBall = -1;
|
||||
|
||||
// check for possible problems if AI karts were incorrectly added
|
||||
if(getNumKarts() > race_manager->getNumPlayers())
|
||||
@@ -61,7 +63,6 @@ void SoccerWorld::init()
|
||||
exit(1);
|
||||
}
|
||||
m_goal_target = race_manager->getMaxGoal();
|
||||
printf("Max Goal: %d\n", m_goal_target);
|
||||
m_goal_sound = sfx_manager->createSoundSource("goal_scored");
|
||||
|
||||
} // init
|
||||
@@ -79,7 +80,11 @@ void SoccerWorld::reset()
|
||||
// Reset original positions for the soccer balls
|
||||
TrackObjectManager* tom = getTrack()->getTrackObjectManager();
|
||||
assert(tom);
|
||||
|
||||
m_redScorers.clear();
|
||||
m_redScoreTimes.clear();
|
||||
m_blueScorers.clear();
|
||||
m_blueScoreTimes.clear();
|
||||
m_lastKartToHitBall = -1;
|
||||
PtrVector<TrackObject>& objects = tom->getObjects();
|
||||
for(int i=0; i<objects.size(); i++)
|
||||
{
|
||||
@@ -90,9 +95,6 @@ void SoccerWorld::reset()
|
||||
obj->reset();
|
||||
obj->getPhysics()->reset();
|
||||
}
|
||||
|
||||
World *world = World::getWorld();
|
||||
world->setClockMode(World::CLOCK_NONE);
|
||||
|
||||
initKartList();
|
||||
} // reset
|
||||
@@ -111,9 +113,22 @@ const std::string& SoccerWorld::getIdent() const
|
||||
*/
|
||||
void SoccerWorld::update(float dt)
|
||||
{
|
||||
World *world = World::getWorld();
|
||||
|
||||
WorldWithRank::update(dt);
|
||||
WorldWithRank::updateTrack(dt);
|
||||
|
||||
if (world->getPhase() == World::GOAL_PHASE)
|
||||
{
|
||||
m_goal_timer += dt;
|
||||
|
||||
if (m_goal_timer > 3.0f)
|
||||
{
|
||||
world->setPhase(WorldStatus::RACE_PHASE);
|
||||
m_goal_timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
} // update
|
||||
|
||||
@@ -131,8 +146,18 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal)
|
||||
//printf("Score:\nTeam One %d : %d Team Two\n", m_team_goals[0], m_team_goals[1]);
|
||||
World *world = World::getWorld();
|
||||
world->setPhase(WorldStatus::GOAL_PHASE);
|
||||
world->setClockMode(World::CLOCK_COUNTDOWN, 1.0);
|
||||
m_goal_sound->play();
|
||||
if(m_lastKartToHitBall != -1)
|
||||
{
|
||||
if(first_goal){
|
||||
m_redScorers.push_back(m_lastKartToHitBall);
|
||||
m_redScoreTimes.push_back(world->getTime());
|
||||
}
|
||||
else{
|
||||
m_blueScorers.push_back(m_lastKartToHitBall);
|
||||
m_blueScoreTimes.push_back(world->getTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//m_check_goals_enabled = false; // TODO: remove?
|
||||
@@ -168,6 +193,13 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal)
|
||||
// TODO: rescue the karts
|
||||
} // onCheckGoalTriggered
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets the last kart that hit the ball, to be able to
|
||||
* identify the scorer later.
|
||||
*/
|
||||
void SoccerWorld::setLastKartTohitBall(unsigned int kartId){
|
||||
m_lastKartToHitBall = kartId;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
/** The battle is over if only one kart is left, or no player kart.
|
||||
*/
|
||||
@@ -361,7 +393,7 @@ void SoccerWorld::initKartList()
|
||||
for(unsigned int i=0; i<kart_amount; i++)
|
||||
{
|
||||
scene::ISceneNode *arrowNode;
|
||||
float arrow_pos_height = m_karts[i]->getKartModel()->getHeight()+0.5;
|
||||
float arrow_pos_height = m_karts[i]->getKartModel()->getHeight()+0.5f;
|
||||
|
||||
if(race_manager->getLocalKartInfo(i).getSoccerTeam() == SOCCER_TEAM_RED)
|
||||
arrowNode = irr_driver->addBillboard(core::dimension2d<irr::f32>(0.3f,0.3f),
|
||||
@@ -450,8 +482,4 @@ AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index,
|
||||
} // createKart
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void SoccerWorld::countdownReachedZero()
|
||||
{
|
||||
World *world = World::getWorld();
|
||||
world->setPhase(World::RACE_PHASE);
|
||||
} // countdownReachedZero
|
||||
|
||||
|
||||
@@ -49,7 +49,13 @@ private:
|
||||
and re-enabled when the next game can be played)*/
|
||||
bool m_can_score_points;
|
||||
SFXBase *m_goal_sound;
|
||||
|
||||
/** Timer for displaying goal text*/
|
||||
float m_goal_timer;
|
||||
int m_lastKartToHitBall;
|
||||
std::vector<int> m_redScorers;
|
||||
std::vector<float> m_redScoreTimes;
|
||||
std::vector<int> m_blueScorers;
|
||||
std::vector<float> m_blueScoreTimes;
|
||||
public:
|
||||
|
||||
SoccerWorld();
|
||||
@@ -75,10 +81,23 @@ public:
|
||||
|
||||
virtual void update(float dt);
|
||||
|
||||
virtual void countdownReachedZero();
|
||||
|
||||
void onCheckGoalTriggered(bool first_goal);
|
||||
int getTeamLeader(unsigned int i);
|
||||
void setLastKartTohitBall(unsigned int kartId);
|
||||
std::vector<int> getScorers(unsigned int team)
|
||||
{
|
||||
if(team == 0)
|
||||
return m_redScorers;
|
||||
else
|
||||
return m_blueScorers;
|
||||
}
|
||||
std::vector<float> getScoreTimes(unsigned int team)
|
||||
{
|
||||
if(team == 0)
|
||||
return m_redScoreTimes;
|
||||
else
|
||||
return m_blueScoreTimes;
|
||||
}
|
||||
|
||||
private:
|
||||
void initKartList();
|
||||
|
||||
@@ -327,7 +327,7 @@ Controller* World::loadAIController(AbstractKart *kart)
|
||||
{
|
||||
Controller *controller;
|
||||
int turn=0;
|
||||
// If different AIs should be used, adjust turn (or switch randomly
|
||||
// If different AIs 8should be used, adjust turn (or switch randomly
|
||||
// or dependent on difficulty)
|
||||
switch(turn)
|
||||
{
|
||||
|
||||
@@ -132,7 +132,7 @@ void WorldStatus::update(const float dt)
|
||||
case SETUP_PHASE:
|
||||
m_auxiliary_timer = 0.0f;
|
||||
m_phase = TRACK_INTRO_PHASE;
|
||||
if (UserConfigParams::m_music && m_play_racestart_sounds)
|
||||
if (m_play_racestart_sounds)
|
||||
{
|
||||
m_track_intro_sound->play();
|
||||
}
|
||||
@@ -148,6 +148,9 @@ void WorldStatus::update(const float dt)
|
||||
if(m_track_intro_sound->getStatus()==SFXManager::SFX_PLAYING
|
||||
&& m_auxiliary_timer<3.5f)
|
||||
return;
|
||||
// Wait before ready phase if sounds are disabled
|
||||
if(!UserConfigParams::m_sfx && m_auxiliary_timer<3.0f)
|
||||
return;
|
||||
m_auxiliary_timer = 0.0f;
|
||||
if (m_play_racestart_sounds) m_prestart_sound->play();
|
||||
m_phase = READY_PHASE;
|
||||
|
||||
@@ -528,6 +528,11 @@ void PhysicalObject::handleExplosion(const Vec3& pos, bool direct_hit)
|
||||
|
||||
} // handleExplosion
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool PhysicalObject::isSoccerBall()
|
||||
{
|
||||
return m_object->isSoccerBall();
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
/* EOF */
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "utils/vec3.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
|
||||
|
||||
class XMLNode;
|
||||
class TrackObject;
|
||||
|
||||
@@ -138,6 +139,7 @@ public:
|
||||
virtual void handleExplosion(const Vec3& pos, bool directHit);
|
||||
void update (float dt);
|
||||
void init ();
|
||||
bool isSoccerBall();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the rigid body of this physical object. */
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "physics/stk_dynamics_world.hpp"
|
||||
#include "physics/triangle_mesh.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "modes/soccer_world.hpp"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Initialise physics.
|
||||
@@ -188,6 +189,12 @@ void Physics::update(float dt)
|
||||
const KartProperties* kp = kart->getKartProperties();
|
||||
kart->setSquash(kp->getSquashDuration(), kp->getSquashSlowdown());
|
||||
}
|
||||
else if(obj->isSoccerBall())
|
||||
{
|
||||
int kartId = p->getUserPointer(1)->getPointerKart()->getWorldKartId();
|
||||
SoccerWorld* soccerWorld = (SoccerWorld*)World::getWorld();
|
||||
soccerWorld->setLastKartTohitBall(kartId);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -228,6 +235,13 @@ void Physics::update(float dt)
|
||||
// -------------------------------
|
||||
p->getUserPointer(0)->getPointerFlyable()
|
||||
->hit(NULL, p->getUserPointer(1)->getPointerPhysicalObject());
|
||||
PhysicalObject* obj = p->getUserPointer(1)->getPointerPhysicalObject();
|
||||
if(obj->isSoccerBall())
|
||||
{
|
||||
int kartId = p->getUserPointer(0)->getPointerFlyable()->getOwnerId();
|
||||
SoccerWorld* soccerWorld = (SoccerWorld*)World::getWorld();
|
||||
soccerWorld->setLastKartTohitBall(kartId);
|
||||
}
|
||||
|
||||
}
|
||||
else if(p->getUserPointer(1)->is(UserPointer::UP_KART))
|
||||
|
||||
@@ -136,7 +136,7 @@ void AddonsScreen::init()
|
||||
|
||||
m_reloading = false;
|
||||
|
||||
m_sort_desc = true;
|
||||
m_sort_desc = false;
|
||||
m_sort_default = true;
|
||||
m_sort_col = 0;
|
||||
|
||||
@@ -389,8 +389,8 @@ void AddonsScreen::onColumnClicked(int column_id)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sort_default = m_sort_desc && !m_sort_default;
|
||||
if (!m_sort_default) m_sort_desc = !m_sort_desc;
|
||||
m_sort_default = !m_sort_desc && !m_sort_default;
|
||||
}
|
||||
|
||||
m_sort_col = column_id;
|
||||
|
||||
@@ -330,7 +330,7 @@ void FeatureUnlockedCutScene::init()
|
||||
m_unlocked_stuff[n].m_root_gift_node = kart_model->attachModel(true);
|
||||
kart_model->setAnimation(KartModel::AF_DEFAULT);
|
||||
float susp[4]={0,0,0,0};
|
||||
kart_model->update(0.0f, 0.0f, susp);
|
||||
kart_model->update(0.0f, 0.0f, susp, 0.0f);
|
||||
|
||||
#ifdef DEBUG
|
||||
m_unlocked_stuff[n].m_root_gift_node->setName("unlocked kart");
|
||||
|
||||
@@ -340,7 +340,7 @@ void GrandPrixLose::setKarts(std::vector<std::string> ident_arg)
|
||||
kart_main_node->updateAbsolutePosition();
|
||||
kart_main_node->setRotation(vector3df(0, 90, 0));
|
||||
float susp[4]={0,0,0,0};
|
||||
kart_model->update(0.0f, 0.0f, susp);
|
||||
kart_model->update(0.0f, 0.0f, susp, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -451,7 +451,7 @@ void GrandPrixWin::setKarts(const std::string idents_arg[3])
|
||||
m_kart_z[n]) );
|
||||
kart_main_node->setScale( core::vector3df(0.4f, 0.4f, 0.4f) );
|
||||
float susp[4]={0,0,0,0};
|
||||
kart_model->update(0.0f, 0.0f, susp);
|
||||
kart_model->update(0.0f, 0.0f, susp, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -392,6 +392,11 @@ public:
|
||||
kart_model.getWheelGraphicsPosition(2) );
|
||||
m_model_view->addModel( kart_model.getWheelModel(3),
|
||||
kart_model.getWheelGraphicsPosition(3) );
|
||||
for(size_t i=0 ; i < kart_model.getSpeedWeightedObjectsCount() ; i++)
|
||||
{
|
||||
const SpeedWeightedObject& obj = kart_model.getSpeedWeightedObject(i);
|
||||
m_model_view->addModel(obj.m_model, obj.m_position);
|
||||
}
|
||||
m_model_view->setRotateContinuously( 35.0f );
|
||||
|
||||
// ---- Kart name label
|
||||
@@ -954,6 +959,11 @@ public:
|
||||
kart_model.getWheelGraphicsPosition(2) );
|
||||
w3->addModel( kart_model.getWheelModel(3),
|
||||
kart_model.getWheelGraphicsPosition(3) );
|
||||
for(size_t i=0 ; i < kart_model.getSpeedWeightedObjectsCount() ; i++)
|
||||
{
|
||||
const SpeedWeightedObject& obj = kart_model.getSpeedWeightedObject(i);
|
||||
w3->addModel(obj.m_model, obj.m_position);
|
||||
}
|
||||
w3->update(0);
|
||||
|
||||
m_parent->m_kart_widgets[playerID].m_kart_name
|
||||
|
||||
@@ -275,8 +275,8 @@ void RaceGUI::drawScores()
|
||||
default: break;
|
||||
}
|
||||
core::rect<s32> indicatorPos(offsetX, offsetY,
|
||||
offsetX + m_marker_player_size/1.25,
|
||||
offsetY + m_marker_player_size/1.25);
|
||||
offsetX + (int)(m_marker_player_size/1.25f),
|
||||
offsetY + (int)(m_marker_player_size/1.25f));
|
||||
core::rect<s32> sourceRect(core::position2d<s32>(0,0),
|
||||
team_icon->getOriginalSize());
|
||||
irr_driver->getVideoDriver()->draw2DImage(team_icon,indicatorPos,sourceRect,
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "tracks/track.hpp"
|
||||
#include "tracks/track_manager.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
DEFINE_SCREEN_SINGLETON( RaceResultGUI );
|
||||
|
||||
@@ -80,6 +81,12 @@ void RaceResultGUI::tearDown()
|
||||
{
|
||||
Screen::tearDown();
|
||||
m_font->setMonospaceDigits(m_was_monospace);
|
||||
|
||||
if (m_finish_sound != NULL &&
|
||||
m_finish_sound->getStatus() == SFXManager::SFX_PLAYING)
|
||||
{
|
||||
m_finish_sound->stop();
|
||||
}
|
||||
} // tearDown
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -298,14 +305,6 @@ void RaceResultGUI::onConfirm()
|
||||
*/
|
||||
void RaceResultGUI::determineTableLayout()
|
||||
{
|
||||
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
|
||||
{
|
||||
redTeamTexture = irr_driver->getTexture(
|
||||
file_manager->getTextureFile("soccer_ball_red.png"));
|
||||
blueTeamTexture = irr_driver->getTexture(
|
||||
file_manager->getTextureFile("soccer_ball_blue.png"));
|
||||
}
|
||||
|
||||
GUIEngine::Widget *table_area = getWidget("result-table");
|
||||
|
||||
m_font = GUIEngine::getFont();
|
||||
@@ -520,6 +519,8 @@ void RaceResultGUI::onUpdate(float dt, irr::video::IVideoDriver*)
|
||||
*/
|
||||
void RaceResultGUI::renderGlobal(float dt)
|
||||
{
|
||||
bool isSoccerWorld = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER;
|
||||
|
||||
m_timer += dt;
|
||||
assert(World::getWorld()->getPhase()==WorldStatus::RESULT_DISPLAY_PHASE);
|
||||
unsigned int num_karts = m_all_row_infos.size();
|
||||
@@ -625,49 +626,54 @@ void RaceResultGUI::renderGlobal(float dt)
|
||||
// Second phase: update X and Y positions for the various animations
|
||||
// =================================================================
|
||||
float v = 0.9f*UserConfigParams::m_width/m_time_single_scroll;
|
||||
for(unsigned int i=0; i<m_all_row_infos.size(); i++)
|
||||
if(!isSoccerWorld)
|
||||
{
|
||||
RowInfo *ri = &(m_all_row_infos[i]);
|
||||
float x = ri->m_x_pos;
|
||||
float y = ri->m_y_pos;
|
||||
switch(m_animation_state)
|
||||
for(unsigned int i=0; i<m_all_row_infos.size(); i++)
|
||||
{
|
||||
// Both states use the same scrolling:
|
||||
case RR_INIT: break; // Remove compiler warning
|
||||
case RR_RACE_RESULT:
|
||||
case RR_OLD_GP_RESULTS:
|
||||
if(m_timer > ri->m_start_at)
|
||||
{ // if active
|
||||
ri->m_x_pos -= dt*v;
|
||||
if(ri->m_x_pos<m_leftmost_column)
|
||||
ri->m_x_pos = (float)m_leftmost_column;
|
||||
x = ri->m_x_pos;
|
||||
}
|
||||
break;
|
||||
case RR_INCREASE_POINTS:
|
||||
ri->m_current_displayed_points +=
|
||||
dt*race_manager->getPositionScore(1)/m_time_for_points;
|
||||
if(ri->m_current_displayed_points>ri->m_new_overall_points)
|
||||
RowInfo *ri = &(m_all_row_infos[i]);
|
||||
float x = ri->m_x_pos;
|
||||
float y = ri->m_y_pos;
|
||||
switch(m_animation_state)
|
||||
{
|
||||
ri->m_current_displayed_points =
|
||||
(float)ri->m_new_overall_points;
|
||||
}
|
||||
ri->m_new_points -=
|
||||
dt*race_manager->getPositionScore(1)/m_time_for_points;
|
||||
if(ri->m_new_points<0)
|
||||
ri->m_new_points = 0;
|
||||
break;
|
||||
case RR_RESORT_TABLE:
|
||||
x = ri->m_x_pos
|
||||
- ri->m_radius*sin(m_timer/m_time_rotation*M_PI);
|
||||
y = ri->m_centre_point
|
||||
+ ri->m_radius*cos(m_timer/m_time_rotation*M_PI);
|
||||
break;
|
||||
case RR_WAIT_TILL_END:
|
||||
break;
|
||||
} // switch
|
||||
displayOneEntry((unsigned int)x, (unsigned int)y, i, true);
|
||||
} // for i
|
||||
// Both states use the same scrolling:
|
||||
case RR_INIT: break; // Remove compiler warning
|
||||
case RR_RACE_RESULT:
|
||||
case RR_OLD_GP_RESULTS:
|
||||
if(m_timer > ri->m_start_at)
|
||||
{ // if active
|
||||
ri->m_x_pos -= dt*v;
|
||||
if(ri->m_x_pos<m_leftmost_column)
|
||||
ri->m_x_pos = (float)m_leftmost_column;
|
||||
x = ri->m_x_pos;
|
||||
}
|
||||
break;
|
||||
case RR_INCREASE_POINTS:
|
||||
ri->m_current_displayed_points +=
|
||||
dt*race_manager->getPositionScore(1)/m_time_for_points;
|
||||
if(ri->m_current_displayed_points>ri->m_new_overall_points)
|
||||
{
|
||||
ri->m_current_displayed_points =
|
||||
(float)ri->m_new_overall_points;
|
||||
}
|
||||
ri->m_new_points -=
|
||||
dt*race_manager->getPositionScore(1)/m_time_for_points;
|
||||
if(ri->m_new_points<0)
|
||||
ri->m_new_points = 0;
|
||||
break;
|
||||
case RR_RESORT_TABLE:
|
||||
x = ri->m_x_pos
|
||||
- ri->m_radius*sin(m_timer/m_time_rotation*M_PI);
|
||||
y = ri->m_centre_point
|
||||
+ ri->m_radius*cos(m_timer/m_time_rotation*M_PI);
|
||||
break;
|
||||
case RR_WAIT_TILL_END:
|
||||
break;
|
||||
} // switch
|
||||
displayOneEntry((unsigned int)x, (unsigned int)y, i, true);
|
||||
} // for i
|
||||
}
|
||||
else
|
||||
displaySoccerResults();
|
||||
|
||||
// Display highscores
|
||||
if (race_manager->getMajorMode() != RaceManager::MAJOR_MODE_GRAND_PRIX ||
|
||||
@@ -744,12 +750,6 @@ void RaceResultGUI::determineGPLayout()
|
||||
void RaceResultGUI::displayOneEntry(unsigned int x, unsigned int y,
|
||||
unsigned int n, bool display_points)
|
||||
{
|
||||
SoccerWorld* soccerWorld = (SoccerWorld*)World::getWorld();
|
||||
bool isSoccerMode = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER;
|
||||
int m_team_goals[2] = {soccerWorld->getScore(0), soccerWorld->getScore(1)};
|
||||
|
||||
if (isSoccerMode && n > 0) return;
|
||||
|
||||
RowInfo *ri = &(m_all_row_infos[n]);
|
||||
video::SColor color = ri->m_is_player_kart
|
||||
? video::SColor(255,255,0, 0 )
|
||||
@@ -770,73 +770,29 @@ void RaceResultGUI::displayOneEntry(unsigned int x, unsigned int y,
|
||||
|
||||
// First draw the icon
|
||||
// -------------------
|
||||
if (!isSoccerMode)
|
||||
if(ri->m_kart_icon)
|
||||
{
|
||||
if(ri->m_kart_icon)
|
||||
{
|
||||
core::recti source_rect(core::vector2di(0,0),
|
||||
ri->m_kart_icon->getSize());
|
||||
core::recti dest_rect(current_x, y,
|
||||
current_x+m_width_icon, y+m_width_icon);
|
||||
irr_driver->getVideoDriver()->draw2DImage(ri->m_kart_icon, dest_rect,
|
||||
source_rect, NULL, NULL,
|
||||
true);
|
||||
}
|
||||
|
||||
current_x += m_width_icon + m_width_column_space;
|
||||
core::recti source_rect(core::vector2di(0,0),
|
||||
ri->m_kart_icon->getSize());
|
||||
core::recti dest_rect(current_x, y,
|
||||
current_x+m_width_icon, y+m_width_icon);
|
||||
irr_driver->getVideoDriver()->draw2DImage(ri->m_kart_icon, dest_rect,
|
||||
source_rect, NULL, NULL,
|
||||
true);
|
||||
}
|
||||
|
||||
current_x += m_width_icon + m_width_column_space;
|
||||
|
||||
// Draw the name
|
||||
// -------------
|
||||
if (!isSoccerMode)
|
||||
{
|
||||
core::recti pos_name(current_x, y,
|
||||
UserConfigParams::m_width, y+m_distance_between_rows);
|
||||
m_font->draw(ri->m_kart_name, pos_name, color, false, false, NULL,
|
||||
true /* ignoreRTL */);
|
||||
current_x += m_width_kart_name + m_width_column_space;
|
||||
}
|
||||
|
||||
// Draw icon, name of team which won in soccer mode and score
|
||||
// ----------------------------------------------------------
|
||||
if (isSoccerMode)
|
||||
{
|
||||
core::stringw text;
|
||||
irr::video::ITexture *team_icon;
|
||||
if (m_team_goals[0] > m_team_goals[1])
|
||||
{
|
||||
text = core::stringw(_("Red team won"));
|
||||
team_icon = redTeamTexture;
|
||||
}
|
||||
else if (m_team_goals[0] < m_team_goals[1])
|
||||
{
|
||||
text = core::stringw(_("Blue team won"));
|
||||
team_icon = blueTeamTexture;
|
||||
}
|
||||
else
|
||||
text = core::stringw(_("Draw"));
|
||||
core::recti pos_name(current_x, y,
|
||||
UserConfigParams::m_width, y+m_distance_between_rows);
|
||||
m_font->draw(ri->m_kart_name, pos_name, color, false, false, NULL,
|
||||
true /* ignoreRTL */);
|
||||
current_x += m_width_kart_name + m_width_column_space;
|
||||
|
||||
core::recti source_rect(core::vector2di(0,0), team_icon->getSize());
|
||||
core::recti dest_rect(current_x, y, current_x+m_width_icon, y+m_width_icon);
|
||||
irr_driver->getVideoDriver()->draw2DImage(team_icon, dest_rect,
|
||||
source_rect, NULL, NULL,
|
||||
true);
|
||||
|
||||
current_x += m_width_icon + m_width_column_space;
|
||||
core::recti pos_name(current_x, y,
|
||||
UserConfigParams::m_width, y+m_distance_between_rows);
|
||||
|
||||
m_font->draw(text, pos_name, color, false, false, NULL, true /* ignoreRTL */);
|
||||
core::dimension2du rect = m_font->getDimension(text.c_str());
|
||||
current_x += rect.Width + 2*m_width_column_space;
|
||||
|
||||
text = core::stringw(m_team_goals[0]) + " : " + core::stringw(m_team_goals[1]);
|
||||
dest_rect = core::recti(current_x, y, current_x+100, y+10);
|
||||
m_font->draw(text, dest_rect, color, false, false, NULL, true /* ignoreRTL */);
|
||||
rect = m_font->getDimension(text.c_str());
|
||||
current_x += rect.Width + 2*m_width_column_space;
|
||||
}
|
||||
|
||||
|
||||
// Draw the time except in FTL mode
|
||||
// --------------------------------
|
||||
if(race_manager->getMinorMode()!=RaceManager::MINOR_MODE_FOLLOW_LEADER)
|
||||
@@ -882,6 +838,145 @@ void RaceResultGUI::displayOneEntry(unsigned int x, unsigned int y,
|
||||
}
|
||||
} // displayOneEntry
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceResultGUI::displaySoccerResults()
|
||||
{
|
||||
|
||||
//Draw win text
|
||||
core::stringw resultText;
|
||||
static video::SColor color = video::SColor(255, 255, 255, 255);
|
||||
gui::IGUIFont* font = GUIEngine::getTitleFont();
|
||||
int currX = UserConfigParams::m_width/2;
|
||||
RowInfo *ri = &(m_all_row_infos[0]);
|
||||
int currY = (int)ri->m_y_pos;
|
||||
SoccerWorld* soccerWorld = (SoccerWorld*)World::getWorld();
|
||||
int teamScore[2] = {soccerWorld->getScore(0), soccerWorld->getScore(1)};
|
||||
|
||||
GUIEngine::Widget *table_area = getWidget("result-table");
|
||||
int height = table_area->m_h + table_area->m_y;
|
||||
|
||||
if(teamScore[0] > teamScore[1])
|
||||
{
|
||||
resultText = _("Red Team Wins");
|
||||
}
|
||||
else if(teamScore[1] > teamScore[0])
|
||||
{
|
||||
resultText = _("Blue Team Wins");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Cannot really happen now. Only in time limited matches.
|
||||
resultText = _("It's a draw");
|
||||
}
|
||||
core::rect<s32> pos(currX, currY, currX, currY);
|
||||
font->draw(resultText.c_str(), pos, color, true, true);
|
||||
|
||||
core::dimension2du rect = m_font->getDimension(resultText.c_str());
|
||||
|
||||
//Draw team scores:
|
||||
currY += rect.Height;
|
||||
currX /= 2;
|
||||
irr::video::ITexture* redTeamIcon = irr_driver->getTexture(
|
||||
file_manager->getTextureFile("soccer_ball_red.png"));
|
||||
irr::video::ITexture* blueTeamIcon = irr_driver->getTexture(
|
||||
file_manager->getTextureFile("soccer_ball_blue.png"));
|
||||
|
||||
core::recti sourceRect(core::vector2di(0,0), redTeamIcon->getSize());
|
||||
core::recti destRect(currX, currY, currX+redTeamIcon->getSize().Width/2,
|
||||
currY+redTeamIcon->getSize().Height/2);
|
||||
irr_driver->getVideoDriver()->draw2DImage(redTeamIcon, destRect,sourceRect,
|
||||
NULL,NULL, true);
|
||||
currX += UserConfigParams::m_width/2 - redTeamIcon->getSize().Width/2;
|
||||
destRect = core::recti(currX, currY, currX+redTeamIcon->getSize().Width/2,
|
||||
currY+redTeamIcon->getSize().Height/2);
|
||||
irr_driver->getVideoDriver()->draw2DImage(blueTeamIcon,destRect,sourceRect,
|
||||
NULL, NULL, true);
|
||||
|
||||
resultText = StringUtils::toWString(teamScore[1]);
|
||||
rect = m_font->getDimension(resultText.c_str());
|
||||
currX += redTeamIcon->getSize().Width/4;
|
||||
currY += redTeamIcon->getSize().Height/2 + rect.Height/4;
|
||||
pos = core::rect<s32>(currX, currY, currX, currY);
|
||||
color = video::SColor(255,255,255,255);
|
||||
font->draw(resultText.c_str(), pos, color, true, false);
|
||||
|
||||
currX -= UserConfigParams::m_width/2 - redTeamIcon->getSize().Width/2;
|
||||
resultText = StringUtils::toWString(teamScore[0]);
|
||||
pos = core::rect<s32>(currX,currY,currX,currY);
|
||||
font->draw(resultText.c_str(), pos, color, true, false);
|
||||
|
||||
int centerX = UserConfigParams::m_width/2;
|
||||
pos = core::rect<s32>(centerX, currY, centerX, currY);
|
||||
font->draw("-", pos, color, true, false);
|
||||
|
||||
//Draw goal scorers:
|
||||
//The red scorers:
|
||||
currY += rect.Height/2 + rect.Height/4;
|
||||
font = GUIEngine::getSmallFont();
|
||||
std::vector<int> scorers = soccerWorld->getScorers(0);
|
||||
std::vector<float> scoreTimes = soccerWorld->getScoreTimes(0);
|
||||
irr::video::ITexture* scorerIcon;
|
||||
|
||||
int prevY = currY;
|
||||
for(unsigned int i=0; i<scorers.size(); i++)
|
||||
{
|
||||
resultText = soccerWorld->getKart(scorers.at(i))->
|
||||
getKartProperties()->getName();
|
||||
resultText.append(" ");
|
||||
resultText.append(StringUtils::timeToString(scoreTimes.at(i)).c_str());
|
||||
rect = m_font->getDimension(resultText.c_str());
|
||||
|
||||
if(height-prevY < ((short)scorers.size()+1)*(short)rect.Height)
|
||||
currY += (height-prevY)/((short)scorers.size()+1);
|
||||
else
|
||||
currY += rect.Height;
|
||||
|
||||
if(currY > height) break;
|
||||
|
||||
pos = core::rect<s32>(currX,currY,currX,currY);
|
||||
font->draw(resultText,pos, color, true, false);
|
||||
scorerIcon = soccerWorld->getKart(scorers.at(i))->
|
||||
getKartProperties()->getIconMaterial()->getTexture();
|
||||
sourceRect = core::recti(core::vector2di(0,0), scorerIcon->getSize());
|
||||
irr::u32 offsetX = GUIEngine::getFont()->getDimension(resultText.c_str()).Width/2;
|
||||
destRect = core::recti(currX-offsetX-30, currY, currX-offsetX, currY+ 30);
|
||||
irr_driver->getVideoDriver()->draw2DImage(scorerIcon, destRect, sourceRect,
|
||||
NULL, NULL, true);
|
||||
}
|
||||
|
||||
//The blue scorers:
|
||||
currY = prevY;
|
||||
currX += UserConfigParams::m_width/2 - redTeamIcon->getSize().Width/2;
|
||||
scorers = soccerWorld->getScorers(1);
|
||||
scoreTimes = soccerWorld->getScoreTimes(1);
|
||||
for(unsigned int i=0; i<scorers.size(); i++)
|
||||
{
|
||||
resultText = soccerWorld->getKart(scorers.at(i))->
|
||||
getKartProperties()->getName();
|
||||
resultText.append(" ");
|
||||
resultText.append(StringUtils::timeToString(scoreTimes.at(i)).c_str());
|
||||
rect = m_font->getDimension(resultText.c_str());
|
||||
|
||||
if(height-prevY < ((short)scorers.size()+1)*(short)rect.Height)
|
||||
currY += (height-prevY)/((short)scorers.size()+1);
|
||||
else
|
||||
currY += rect.Height;
|
||||
|
||||
if(currY > height) break;
|
||||
|
||||
pos = core::rect<s32>(currX,currY,currX,currY);
|
||||
font->draw(resultText,pos, color, true, false);
|
||||
scorerIcon = soccerWorld->getKart(scorers.at(i))->
|
||||
getKartProperties()->getIconMaterial()->getTexture();
|
||||
sourceRect = core::recti(core::vector2di(0,0), scorerIcon->getSize());
|
||||
irr::u32 offsetX = GUIEngine::getFont()->getDimension(resultText.c_str()).Width/2;
|
||||
|
||||
destRect = core::recti(currX-offsetX-30, currY, currX-offsetX, currY+ 30);
|
||||
irr_driver->getVideoDriver()->draw2DImage(scorerIcon, destRect, sourceRect,
|
||||
NULL, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void RaceResultGUI::clearHighscores()
|
||||
|
||||
@@ -110,8 +110,6 @@ private:
|
||||
}; // Rowinfo
|
||||
|
||||
/** The team icons. */
|
||||
video::ITexture *redTeamTexture;
|
||||
video::ITexture *blueTeamTexture;
|
||||
|
||||
std::vector<RowInfo> m_all_row_infos;
|
||||
|
||||
@@ -198,6 +196,7 @@ private:
|
||||
void displayGPProgress();
|
||||
void cleanupGPProgress();
|
||||
void displayHighScores();
|
||||
void displaySoccerResults();
|
||||
public:
|
||||
|
||||
RaceResultGUI();
|
||||
|
||||
@@ -35,7 +35,7 @@ using namespace GUIEngine;
|
||||
DEFINE_SCREEN_SINGLETON( SoccerSetupScreen );
|
||||
|
||||
#define KART_CONTINUOUS_ROTATION_SPEED 35.f
|
||||
#define KART_CONFIRMATION_ROTATION_SPEED 0.f
|
||||
#define KART_CONFIRMATION_ROTATION_SPEED 4.f
|
||||
#define KART_CONFIRMATION_TARGET_ANGLE 10.f
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -56,7 +56,7 @@ void SoccerSetupScreen::eventCallback(Widget* widget, const std::string& name, c
|
||||
if(name == "continue")
|
||||
{
|
||||
StateManager::get()->pushScreen( ArenasScreen::getInstance() );
|
||||
race_manager->setMaxGoal(getWidget<SpinnerWidget>("goalamount")->getValue());
|
||||
race_manager->setMaxGoal(getWidget<SpinnerWidget>("goalamount")->getValue());
|
||||
input_manager->setMasterPlayerOnly(true);
|
||||
}
|
||||
else if (name == "back")
|
||||
@@ -184,12 +184,28 @@ GUIEngine::EventPropagation SoccerSetupScreen::filterActions( PlayerAction acti
|
||||
switch(action)
|
||||
{
|
||||
case PA_MENU_LEFT:
|
||||
if (bt_continue->isFocusedForPlayer(PLAYER_ID_GAME_MASTER))
|
||||
if (bt_continue->isFocusedForPlayer(PLAYER_ID_GAME_MASTER) &&
|
||||
m_kart_view_info[playerId].confirmed == false)
|
||||
{
|
||||
team_switch = SOCCER_TEAM_RED;
|
||||
|
||||
for(int i=0 ; i < nb_players ; i++)
|
||||
{
|
||||
m_kart_view_info[i].view->unsetBadge(BAD_BADGE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PA_MENU_RIGHT:
|
||||
if (bt_continue->isFocusedForPlayer(PLAYER_ID_GAME_MASTER))
|
||||
if (bt_continue->isFocusedForPlayer(PLAYER_ID_GAME_MASTER) &&
|
||||
m_kart_view_info[playerId].confirmed == false)
|
||||
{
|
||||
team_switch = SOCCER_TEAM_BLUE;
|
||||
|
||||
for(int i=0 ; i < nb_players ; i++)
|
||||
{
|
||||
m_kart_view_info[i].view->unsetBadge(BAD_BADGE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PA_MENU_UP:
|
||||
if (playerId != PLAYER_ID_GAME_MASTER)
|
||||
@@ -204,13 +220,28 @@ GUIEngine::EventPropagation SoccerSetupScreen::filterActions( PlayerAction acti
|
||||
if (!bt_continue->isFocusedForPlayer(PLAYER_ID_GAME_MASTER) || areAllKartsConfirmed())
|
||||
return result;
|
||||
|
||||
if (getNumConfirmedKarts() > nb_players-2 &&
|
||||
(getNumKartsInTeam(SOCCER_TEAM_RED) == 0 ||
|
||||
getNumKartsInTeam(SOCCER_TEAM_BLUE) == 0))
|
||||
{
|
||||
if (!m_kart_view_info[playerId].confirmed)
|
||||
{
|
||||
sfx_manager->quickSound( "anvil" );
|
||||
m_kart_view_info[playerId].view->setBadge(BAD_BADGE);
|
||||
}
|
||||
return EVENT_BLOCK;
|
||||
}
|
||||
|
||||
// Confirm team selection
|
||||
for(int i=0 ; i < nb_players ; i++)
|
||||
{
|
||||
if(m_kart_view_info[i].local_player_id == playerId)
|
||||
if(m_kart_view_info[i].local_player_id == playerId &&
|
||||
m_kart_view_info[i].confirmed == false)
|
||||
{
|
||||
m_kart_view_info[i].confirmed = true;
|
||||
m_kart_view_info[i].view->setRotateTo( KART_CONFIRMATION_TARGET_ANGLE, KART_CONFIRMATION_ROTATION_SPEED );
|
||||
m_kart_view_info[i].view->setBadge(OK_BADGE);
|
||||
sfx_manager->quickSound( "wee" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -230,8 +261,9 @@ GUIEngine::EventPropagation SoccerSetupScreen::filterActions( PlayerAction acti
|
||||
{
|
||||
m_kart_view_info[i].confirmed = false;
|
||||
m_kart_view_info[i].view->setRotateContinuously( KART_CONTINUOUS_ROTATION_SPEED );
|
||||
break;
|
||||
m_kart_view_info[i].view->unsetBadge(OK_BADGE);
|
||||
}
|
||||
m_kart_view_info[i].view->unsetBadge(BAD_BADGE);
|
||||
}
|
||||
result = EVENT_BLOCK;
|
||||
break;
|
||||
@@ -239,7 +271,7 @@ GUIEngine::EventPropagation SoccerSetupScreen::filterActions( PlayerAction acti
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(team_switch != SOCCER_TEAM_NONE) // A player wants to change his team?
|
||||
{
|
||||
// Find the corresponding kart view, update its team and update the layout
|
||||
@@ -288,6 +320,30 @@ bool SoccerSetupScreen::areAllKartsConfirmed() const
|
||||
return all_confirmed;
|
||||
}
|
||||
|
||||
int SoccerSetupScreen::getNumKartsInTeam(int team)
|
||||
{
|
||||
int karts_in_team = 0;
|
||||
int nb_players = m_kart_view_info.size();
|
||||
for(int i=0 ; i < nb_players ; i++)
|
||||
{
|
||||
if(m_kart_view_info[i].team == team)
|
||||
karts_in_team++;
|
||||
}
|
||||
return karts_in_team;
|
||||
}
|
||||
|
||||
int SoccerSetupScreen::getNumConfirmedKarts()
|
||||
{
|
||||
int confirmed_karts = 0;
|
||||
int nb_players = m_kart_view_info.size();
|
||||
for(int i=0 ; i < nb_players ; i++)
|
||||
{
|
||||
if(m_kart_view_info[i].confirmed == true)
|
||||
confirmed_karts++;
|
||||
}
|
||||
return confirmed_karts;
|
||||
}
|
||||
|
||||
void SoccerSetupScreen::updateKartViewsLayout()
|
||||
{
|
||||
Widget* central_div = getWidget<Widget>("central_div");
|
||||
|
||||
@@ -72,6 +72,8 @@ public:
|
||||
|
||||
private:
|
||||
bool areAllKartsConfirmed() const;
|
||||
int getNumKartsInTeam(int team);
|
||||
int getNumConfirmedKarts();
|
||||
void updateKartViewsLayout();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user