Starting the merge with the swatter branch. Now it should be automatic with karts, but doesn't work with items (yet).

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9275 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
funto66 2011-07-15 23:38:40 +00:00
parent 747489c917
commit d26b406780
21 changed files with 271 additions and 292 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

BIN
data/models/swatter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,63 @@
// skinning.vert
#define MAX_JOINT_NUM 36
#define MAX_LIGHT_NUM 8
uniform mat4 JointTransform[MAX_JOINT_NUM];
void main()
{
int index;
vec4 ecPos;
vec3 normal;
vec3 light_dir;
float n_dot_l;
float dist;
mat4 ModelTransform = gl_ModelViewProjectionMatrix;
index = int(gl_Color.r * 255.99);
mat4 vertTran = JointTransform[index - 1];
index = int(gl_Color.g * 255.99);
if(index > 0)
vertTran += JointTransform[index - 1];
index = int(gl_Color.b * 255.99);
if(index > 0)
vertTran += JointTransform[index - 1];
index = int(gl_Color.a * 255.99);
if(index > 0)
vertTran += JointTransform[index - 1];
ecPos = gl_ModelViewMatrix * vertTran * gl_Vertex;
normal = normalize(gl_NormalMatrix * mat3(vertTran) * gl_Normal);
gl_FrontColor = vec4(0,0,0,0);
for(int i = 0;i < MAX_LIGHT_NUM;i++)
{
light_dir = vec3(gl_LightSource[i].position-ecPos);
n_dot_l = max(dot(normal, normalize(light_dir)), 0.0);
dist = length(light_dir);
n_dot_l *= 1.0 / (gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * dist);
gl_FrontColor += gl_LightSource[i].diffuse * n_dot_l;
}
gl_FrontColor = clamp(gl_FrontColor,0.3,1.0);
ModelTransform *= vertTran;
gl_Position = ModelTransform * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_MultiTexCoord1;
/*
// Reflections.
vec3 r = reflect( ecPos.xyz , normal );
float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) );
gl_TexCoord[1].s = r.x/m + 0.5;
gl_TexCoord[1].t = r.y/m + 0.5;
*/
}

View File

@ -177,17 +177,12 @@
max-speed-increase="5" duration="1" fade-out-time="2"/>
<!-- Kart-specific settings for the swatter:
duration: how long can the swatter be readied.
count: how often can it be used.
distance: How close a kart must be before it can be hit.
animation-time: How long it takes for the swatter to hit a target.
item-animation-time: How long the swatter will swat when a
projectile hits.
duration: how long can the swatter be active.
distance: How close a kart or an item must be before it can be hit.
squash-duration: How long a kart will remain squashed.
squash-slowdown: percentage of max speed that a kart is
restricted to. -->
<swatter duration="10" count="2" distance="3" animation-time="0.2"
item-animation-time="0.04" squash-duration="5"
<swatter duration="10" distance="3" squash-duration="5"
squash-slowdown="0.5"/>
<!-- min-speed-radius and max-speed-radius define the smallest turn

View File

@ -385,7 +385,7 @@ namespace UserConfigParams
PARAM_PREFIX bool m_profiler_enabled PARAM_DEFAULT( false );
/** True if hardware skinning should be enabled */
PARAM_PREFIX bool m_hw_skinning_enabled PARAM_DEFAULT( true );
PARAM_PREFIX bool m_hw_skinning_enabled PARAM_DEFAULT( false );
// not saved to file

View File

@ -26,8 +26,6 @@
void HardwareSkinning::prepareNode(scene::IAnimatedMeshSceneNode *node)
{
return; // BOUM
scene::IAnimatedMesh* mesh = node->getMesh();
video::IVideoDriver* driver = irr_driver->getVideoDriver();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
@ -56,7 +54,7 @@ void HardwareSkinning::prepareNode(scene::IAnimatedMeshSceneNode *node)
// Use VBOs and avoid streaming the vertex data
//mesh->setHardwareMappingHint(scene::EHM_STATIC);
mesh->setHardwareMappingHint(scene::EHM_DYNAMIC); // BOUM
mesh->setHardwareMappingHint(scene::EHM_DYNAMIC); // TODO: is it really better?
// Hardware skinning is not implemented in Irrlicht (as of version 1.7.2) so "enabling" it
// results in the data not being sent and the CPU not computing software skinning.

View File

@ -21,7 +21,7 @@
#include "config/user_config.hpp"
#include "graphics/camera.hpp"
#include "graphics/hardware_skinning.hpp" // BOUM
#include "graphics/hardware_skinning.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/particle_kind_manager.hpp"
#include "graphics/per_camera_node.hpp"
@ -1244,10 +1244,7 @@ void IrrDriver::update(float dt)
kart->getCamera()->activate();
// BEGIN BOUM
m_scene_manager->drawAll();
//m_scene_manager->drawAll();
// END BOUM
PROFILER_POP_CPU_MARKER();

View File

@ -18,8 +18,8 @@
#include "graphics/irr_driver.hpp"
#include "graphics/lod_node.hpp"
#include "graphics/hardware_skinning.hpp" // BOUM
#include "config/user_config.hpp" // BOUM
#include "graphics/hardware_skinning.hpp"
#include "config/user_config.hpp"
#include <ISceneManager.h>
#include <ICameraSceneNode.h>
@ -94,7 +94,6 @@ void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
assert(node != NULL);
// BOUM Funto: why grab(), then remove(), then drop()...??
node->grab();
node->remove();
m_detail.push_back(level*level);
@ -102,10 +101,8 @@ void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
m_nodes_set.insert(node);
node->setParent(this);
// BEGIN BOUM
if(UserConfigParams::m_hw_skinning_enabled && node->getType() == scene::ESNT_ANIMATED_MESH)
HardwareSkinning::prepareNode((scene::IAnimatedMeshSceneNode*)node);
// END BOUM
node->drop();
}

View File

@ -113,9 +113,6 @@ void MaterialManager::adjustForFog(video::ITexture* t,
void MaterialManager::setAllUntexturedMaterialFlags(scene::IMeshBuffer *mb) const
{
// BEGIN BOUM
// for(int i = (int)m_materials.size()-1; i>=0; i-- )
// {
irr::video::SMaterial& material = mb->getMaterial();
if (material.getTexture(0) == NULL)
{
@ -127,8 +124,6 @@ void MaterialManager::setAllUntexturedMaterialFlags(scene::IMeshBuffer *mb) cons
material.ColorMaterial = irr::video::ECM_DIFFUSE_AND_AMBIENT;
material.MaterialType = irr::video::EMT_SOLID;
}
// } // for i
// END BOUM
}
//-----------------------------------------------------------------------------
int MaterialManager::addEntity(Material *m)

View File

@ -48,6 +48,7 @@ Attachment::Attachment(Kart* kart)
std::string debug_name = kart->getIdent()+" (attachment)";
m_node->setName(debug_name.c_str());
#endif
m_node->setAnimationEndCallback(this);
m_node->setParent(m_kart->getNode());
m_node->setVisible(false);
} // Attachment
@ -64,12 +65,14 @@ void Attachment::set(AttachmentType type, float time, Kart *current_kart)
{
clear();
// If necessary create the appropriate plugin which encapsulates
// If necessary create the appropriate plugin which encapsulates the associated behavior
switch(type)
{
case ATTACH_SWATTER :
m_plugin = new Swatter(this, m_kart);
default: break;
break;
default:
break;
} // switch(type)
m_node->setMesh(attachment_manager->getMesh(type));
@ -84,9 +87,6 @@ void Attachment::set(AttachmentType type, float time, Kart *current_kart)
m_time_left = time;
m_previous_owner = current_kart;
m_node->setRotation(core::vector3df(0, 0, 0));
m_count = m_type==ATTACH_SWATTER
? m_kart->getKartProperties()->getSwatterCount()
: 1;
// A parachute can be attached as result of the usage of an item. In this
// case we have to save the current kart speed so that it can be detached
@ -123,6 +123,8 @@ void Attachment::clear()
m_time_left=0.0;
m_node->setVisible(false);
m_node->setPosition(core::vector3df());
m_node->setRotation(core::vector3df());
// Resets the weight of the kart if the previous attachment affected it
// (e.g. anvil). This must be done *after* setting m_type to
@ -253,7 +255,6 @@ void Attachment::update(float dt)
clear(); // also removes the plugin
return;
}
m_node->setRotation(m_plugin->getRotation());
}
switch (m_type)
@ -303,20 +304,9 @@ void Attachment::update(float dt)
} // update
// ----------------------------------------------------------------------------
/** Uses the swatter to swat at an item. The actual functionality is
* implemented in the swatter plugin.
* \pre The item must be an attachment (and m_plugin must be a swatter).
*/
void Attachment::swatItem()
/** Inform any eventual plugin when an animation is done. */
void Attachment::OnAnimationEnd(scene::IAnimatedMeshSceneNode* node)
{
assert(m_type==ATTACH_SWATTER);
((Swatter*)m_plugin)->swatItem();
} // swatItem
// ----------------------------------------------------------------------------
/** Returns if the swatter is currently aiming, i.e. can be used to
* swat an incoming projectile. */
bool Attachment::isSwatterReady() const
{
assert(m_type==ATTACH_SWATTER);
return ((Swatter*)m_plugin)->isSwatterReady();
} // isSwatterReady
if(m_plugin)
m_plugin->onAnimationEnd();
}

View File

@ -41,7 +41,7 @@ class Item;
* a scene node).
* \ingroup items
*/
class Attachment: public NoCopy
class Attachment: public NoCopy, public scene::IAnimationEndCallBack
{
public:
// Some loop in attachment.cpp depend on ATTACH_FIRST and ATTACH_MAX.
@ -66,9 +66,6 @@ private:
/** Kart the attachment is attached to. */
Kart *m_kart;
/** How often an attachment can be used (e.g. swatter). */
int m_count;
/** Time left till attachment expires. */
float m_time_left;
@ -97,8 +94,6 @@ public:
void hitBanana(Item *item, int new_attachment=-1);
void update (float dt);
void moveBombFromTo(Kart *from, Kart *to);
void swatItem();
bool isSwatterReady() const;
void set (AttachmentType type, float time, Kart *previous_kart=NULL);
// ------------------------------------------------------------------------
@ -122,6 +117,11 @@ public:
float weightAdjust() const {
return m_type==ATTACH_ANVIL ? stk_config->m_anvil_weight : 0.0f; }
// ------------------------------------------------------------------------
/** Return the currently associated scene node (used by e.g the swatter) */
scene::IAnimatedMeshSceneNode* getNode() {return m_node;}
// ------------------------------------------------------------------------
/** Implement IAnimatedMeshSceneNode */
virtual void OnAnimationEnd(scene::IAnimatedMeshSceneNode* node);
}; // Attachment
#endif

View File

@ -38,15 +38,18 @@ class Attachment;
class AttachmentPlugin
{
protected:
/** Keeps track of the rotation of an attachment, this base class
* will set it to 0. */
core::vector3df m_rotation;
/** Parent Attachment of this plugin */
Attachment *m_attachment;
/** Kart the attachment is attached to. */
Kart *m_kart;
public:
/** Constructor for a plugin. */
AttachmentPlugin(Attachment *attachment, Kart *kart)
{
m_rotation = core::vector3df(0,0,0);
m_attachment = attachment;
m_kart = kart;
}
virtual ~AttachmentPlugin() {}
@ -57,8 +60,8 @@ public:
virtual bool updateAndTestFinished(float dt) = 0;
// ------------------------------------------------------------------------
/** Returns the rotation of the attachment. */
virtual const core::vector3df& getRotation() const { return m_rotation; }
/** Called when the animation of the Attachment's node is done. */
virtual void onAnimationEnd() {}
}; // AttachmentPlugin
#endif

View File

@ -17,24 +17,36 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// TODO: be able to squash karts
// TODO: use a proportional corrector for avoiding brutal movements
// TODO: make the swatter (and other items) appear and disappear progressively
// TODO: remove the maximum number of squashes
// TODO: add a swatter music
// TODO: be able to squash items
// TODO: move some constants to KartProperties, use all constants from KartProperties
#include "items/swatter.hpp"
#include "items/attachment.hpp"
#include "modes/world.hpp"
#include "karts/kart.hpp"
#define SWAT_ANGLE 22.0f
#define SWAT_POS_OFFSET core::vector3df(0.0, 0.2, -0.4)
#define SWAT_ANGLE_MIN 45
#define SWAT_ANGLE_MAX 135
#define SWAT_ANGLE_OFFSET (90.0f + 15.0f)
#define SWATTER_ANIMATION_SPEED 100.0f
Swatter::Swatter(Attachment *attachment, Kart *kart)
: AttachmentPlugin(attachment, kart)
{
m_kart = kart;
m_count = kart->getKartProperties()->getSwatterCount();
m_animation_timer = 0.0f;
m_animation_phase = SWATTER_AIMING;
m_rot_per_sec = core::vector3df(0,0,0);
m_rotation = core::vector3df(0,0,0);
m_animation_target = NULL;
m_target = NULL;
// Setup the node
scene::IAnimatedMeshSceneNode* node = m_attachment->getNode();
node->setPosition(SWAT_POS_OFFSET);
node->setAnimationSpeed(0);
} // Swatter
//-----------------------------------------------------------------------------
@ -50,181 +62,137 @@ Swatter::~Swatter()
*/
bool Swatter::updateAndTestFinished(float dt)
{
m_rotation += m_rot_per_sec * dt;
switch(m_animation_phase)
{
case SWATTER_AIMING:
aimSwatter();
break;
case SWATTER_TO_KART:
if(fabsf(m_rotation.Z)>=90)
{
checkForHitKart(m_rotation.Z>0);
m_rot_per_sec *= -1.0f;
m_animation_phase = SWATTER_BACK_FROM_KART;
}
break;
case SWATTER_BACK_FROM_KART:
if (m_rotation.Z>0)
{
m_rotation = core::vector3df(0,0,0);
m_rot_per_sec = core::vector3df(0,0,0);
m_animation_phase = SWATTER_AIMING;
m_animation_target = NULL;
}
break;
case SWATTER_ITEM_1: // swatter going to the left
if(m_rotation.Z>SWAT_ANGLE)
{
m_animation_phase = SWATTER_ITEM_2;
m_rot_per_sec *= -1.0f;
}
break;
case SWATTER_ITEM_2: // swatter going all the way to the right
if(m_rotation.Z<-SWAT_ANGLE)
{
m_animation_phase = SWATTER_ITEM_3;
m_rot_per_sec *= -1.0f;
}
break;
case SWATTER_ITEM_3: // swatter going back to rest position.
if(m_rotation.Z>0)
{
m_rotation = core::vector3df(0,0,0);
m_rot_per_sec = core::vector3df(0,0,0);
m_animation_phase = SWATTER_AIMING;
}
break;
} // switch m_animation_phase
chooseTarget();
pointToTarget();
if(!m_target)
break;
// Is the target too near?
float dist_to_target2 = (m_target->getXYZ() - m_attachment->getNode()->getAbsolutePosition()).length2();
float min_dist2 = m_kart->getKartProperties()->getSwatterDistance2();
if(dist_to_target2 < min_dist2)
{
// Start squashing
m_animation_phase = SWATTER_TO_TARGET;
// Setup the animation
scene::IAnimatedMeshSceneNode* node = m_attachment->getNode();
node->setCurrentFrame(0.0f);
node->setLoopMode(false);
node->setAnimationSpeed(SWATTER_ANIMATION_SPEED);
}
}
break;
case SWATTER_TO_TARGET:
{
pointToTarget();
scene::IAnimatedMeshSceneNode *node = m_attachment->getNode();
const float middle_frame = node->getEndFrame()/2.0f;
float current_frame = node->getFrameNr();
// Did we just finish the first part of the movement?
if(current_frame >= middle_frame)
{
// Squash the karts and items around and change the current phase
squashThingsAround();
m_animation_phase = SWATTER_FROM_TARGET;
}
}
break;
case SWATTER_FROM_TARGET:
break;
}
// If the swatter is used up, trigger cleaning up
return (m_count==0);
// TODO: use a timeout
// TODO: how does it work currently...?
return false;
} // updateAndTestFinished
//-----------------------------------------------------------------------------
/** Returns true if the point xyz is to the left of the kart.
* \param xyz Point to determine the direction
*/
bool Swatter::isLeftSideOfKart(const Vec3 &xyz)
/** When the animation ends, the swatter is ready again */
void Swatter::onAnimationEnd()
{
Vec3 forw_vec = m_kart->getTrans().getBasis().getColumn(2);
const Vec3& k1 = m_kart->getXYZ();
const Vec3 k2 = k1+forw_vec;
return xyz.sideOfLine2D(k1, k2)>0;
} // isLeftSideOfKart
m_animation_phase = SWATTER_AIMING;
} // onAnimationEnd
//-----------------------------------------------------------------------------
/** This function is called when the swatter reaches the hit angle (i.e. it
* is furthest down). Check all karts if any one is hit, i.e. is at the right
* side and at the right angle and distance.
* \param isWattingLeft True if the swatter is aiming to the left side
* of the kart.
*/
void Swatter::checkForHitKart(bool isSwattingLeft)
/** Determine the nearest kart or item and update the current target accordingly */
void Swatter::chooseTarget()
{
// Square of the minimum distance
const KartProperties *kp = m_kart->getKartProperties();
float min_dist2 = kp->getSwatterDistance2();
Kart *hit_kart = NULL;
Vec3 forw_vec = m_kart->getTrans().getBasis().getColumn(2);
// TODO: for the moment, only handle karts...
const World *world = World::getWorld();
Kart *closest_kart = NULL;
float min_dist2 = FLT_MAX;
for(unsigned int i=0; i<world->getNumKarts(); i++)
{
Kart *kart = world->getKart(i);
// TODO: isSwatterReady(), isSquashable()?
if(kart->isEliminated() || kart==m_kart || kart->isSquashed())
continue;
float f = (kart->getXYZ()-m_kart->getXYZ()).length2();
// Distance is too great, ignore this kart.
if(f>min_dist2) continue;
// Check if the kart is at the right side.
const bool left = isLeftSideOfKart(kart->getXYZ());
if(left!=isSwattingLeft)
float dist2 = (kart->getXYZ()-m_kart->getXYZ()).length2();
if(dist2<min_dist2)
{
//printf("%s wrong side: %d %d\n",
// kart->getIdent().c_str(), left, isSwattingLeft);
continue;
min_dist2 = dist2;
closest_kart = kart;
}
}
m_target = closest_kart; // may be NULL
}
Vec3 kart_vec = m_kart->getXYZ()-kart->getXYZ();
// cos alpha = a*b/||a||/||b||
// Since forw_vec is a unit vector, we only have to divide by
// the length of the vector to the kart.
float cos_angle = kart_vec.dot(forw_vec)/kart_vec.length();
float angle = acosf(cos_angle)*180/M_PI;
if(angle<45 || angle>135)
/** If there is a current target, point in its direction, otherwise adopt the default position */
void Swatter::pointToTarget()
{
//printf("%s angle %f\n", kart->getIdent().c_str(), angle);
continue;
if(!m_target)
{
m_attachment->getNode()->setRotation(core::vector3df());
}
else
{
Vec3 swatter_to_target = m_target->getXYZ() - m_attachment->getNode()->getAbsolutePosition();
float dy = -swatter_to_target.getZ();
float dx = swatter_to_target.getX();
float angle = SWAT_ANGLE_OFFSET + (atan2(dy, dx) - m_kart->getHeading()) * 180.0f/M_PI;
m_attachment->getNode()->setRotation(core::vector3df(0.0, angle, 0.0));
}
}
/** Squash karts or items that are around the end position (determined using a joint) of the swatter */
void Swatter::squashThingsAround()
{
const KartProperties* kp = m_kart->getKartProperties();
float min_dist2 = kp->getSwatterDistance2(); // Square of the minimum distance
const World* world = World::getWorld();
scene::IAnimatedMeshSceneNode *node = m_attachment->getNode();
// Get the node corresponding to the joint at the center of the swatter (by swatter, I mean
// the thing hold in the hand, not the whole thing)
scene::ISceneNode* swatter_node = node->getJointNode("Swatter");
assert(swatter_node);
Vec3 swatter_pos = swatter_node->getAbsolutePosition();
// Squash karts around
for(unsigned int i=0; i<world->getNumKarts(); i++)
{
Kart *kart = world->getKart(i);
// TODO: isSwatterReady()
if(kart->isEliminated() || kart==m_kart || kart->isSquashed())
continue;
float dist2 = (kart->getXYZ()-swatter_pos).length2();
if(dist2 < min_dist2)
{
kart->setSquash(kp->getSquashDuration(),
kp->getSquashSlowdown());
// It is assumed that only one kart is within reach of the swatter,
// so we can stop testing karts here.
return;
} // for i < num_karts
} // angleToKart
//-----------------------------------------------------------------------------
/** Checks for any kart that is not already squashed that is close enough.
* If a kart is found, it changes the state of the swatter to be
* SWATTER_TARGET and starts the animation.
*/
void Swatter::aimSwatter()
{
const World *world = World::getWorld();
Kart *min_kart = NULL;
// Square of the minimum distance
float min_dist2 = m_kart->getKartProperties()->getSwatterDistance2();
for(unsigned int i=0; i<world->getNumKarts(); i++)
{
Kart *kart = world->getKart(i);
if(kart->isEliminated() || kart==m_kart || kart->isSquashed())
continue;
float f = (kart->getXYZ()-m_kart->getXYZ()).length2();
if(f<min_dist2)
{
min_dist2 = f;
min_kart = kart;
}
}
// No kart close enough, nothing to do.
if(!min_kart) return;
m_count --;
m_animation_phase = SWATTER_TO_KART;
m_animation_target = min_kart;
if(UserConfigParams::logMisc())
printf("[swatter] %s aiming at %s.\n",
m_kart->getIdent().c_str(), min_kart->getIdent().c_str());
const KartProperties *kp = m_kart->getKartProperties();
m_animation_timer = kp->getSwatterAnimationTime();
const bool left = isLeftSideOfKart(min_kart->getXYZ());
m_rot_per_sec = core::vector3df(0, 0,
left ?90.0f:-90.0f) / m_animation_timer;
} // aimSwatter
//-----------------------------------------------------------------------------
/** Starts a (smaller) and faster swatting movement to be played
* when the kart is hit by an item.
*/
void Swatter::swatItem()
{
if(UserConfigParams::logMisc())
printf("[swatter] %s swatting item.\n",
m_kart->getIdent().c_str());
assert(m_animation_target==NULL);
m_animation_phase = SWATTER_ITEM_1;
m_animation_timer =
m_kart->getKartProperties()->getSwatterItemAnimationTime();
m_count--;
m_rot_per_sec = core::vector3df(0, 0, SWAT_ANGLE) / m_animation_timer;
} // swatItem
// TODO: squash items
}

View File

@ -24,6 +24,7 @@
#include "config/stk_config.hpp"
#include "items/attachment_plugin.hpp"
#include "karts/moveable.hpp"
#include "utils/no_copy.hpp"
#include "utils/random_generator.hpp"
@ -38,41 +39,21 @@ class Swatter : public NoCopy, public AttachmentPlugin
{
private:
/** Kart the attachment is attached to. */
Kart *m_kart;
/** How often an attachment can be used (e.g. swatter). */
int m_count;
/** State of a swatter animation. The swatter is either aiming (looking
* for a kart and/or swatting an incoming item), moving towards or back
* from a kart, or swatting left and right to hit an item - which has
* three phases: going left to an angle a (phae 1), then going to -a
* (phase 2), then going back to 0. */
enum {SWATTER_AIMING, SWATTER_TO_KART,
SWATTER_BACK_FROM_KART,
SWATTER_ITEM_1, SWATTER_ITEM_2, SWATTER_ITEM_3,
SWATTER_BACK_FROM_ITEM} m_animation_phase;
/** Timer for swatter animation. */
float m_animation_timer;
/** State of the animation: the swatter is successively:
- aiming (default state) => it's turning to the nearest target
- going down to the target
- going up from the target
*/
enum {SWATTER_AIMING, SWATTER_TO_TARGET, SWATTER_FROM_TARGET}
m_animation_phase;
/** The kart the swatter is aiming at. */
Kart *m_animation_target;
/** Rotation per second so that the swatter will hit the kart. */
core::vector3df m_rot_per_sec;
void aimSwatter();
bool isLeftSideOfKart(const Vec3 &xyz);
void checkForHitKart(bool isSwattingToLeft);
Moveable *m_target;
public:
Swatter(Attachment *attachment, Kart *kart);
virtual ~Swatter();
bool updateAndTestFinished(float dt);
void updateSwatter(float dt);
void swatItem();
// ------------------------------------------------------------------------
/** Returns if the swatter is currently aiming, i.e. can be used to
@ -81,6 +62,18 @@ public:
return m_animation_phase == SWATTER_AIMING;
} // isSwatterReady
// ------------------------------------------------------------------------
virtual void onAnimationEnd();
// ------------------------------------------------------------------------
private:
/** Determine the nearest kart or item and update the current target accordingly */
void chooseTarget();
/** If there is a current target, point to it, otherwise adopt the default position */
void pointToTarget();
/** Squash karts or items that are around the end position (determined using a joint) of the swatter */
void squashThingsAround();
}; // Swatter
#endif

View File

@ -134,16 +134,21 @@ void EmergencyAnimation::forceRescue(bool is_auto_rescue)
void EmergencyAnimation::handleExplosion(const Vec3 &pos, bool direct_hit)
{
// Avoid doing another explosion while a kart is thrown around in the air.
if(playingEmergencyAnimation()) return;
if(playingEmergencyAnimation())
return;
if(m_kart->isInvulnerable())
return;
Attachment *a=m_kart->getAttachment();
// !Funto! TODO: squash items with the swatter...should we do it here or in the Swatter class?
/* Attachment *a=m_kart->getAttachment();
if(a->getType()==Attachment::ATTACH_SWATTER &&
a->isSwatterReady())
{
a->swatItem();
return;
}
*/
m_xyz = m_kart->getXYZ();
// Ignore explosion that are too far away.

View File

@ -91,13 +91,11 @@ KartProperties::KartProperties(const std::string &filename)
m_camera_backward_up_angle = m_explosion_invulnerability_time =
m_rescue_time = m_rescue_height = m_explosion_time =
m_explosion_radius = m_ai_steering_variation =
m_swatter_distance2 = m_swatter_duration = m_swatter_animation_time =
m_swatter_item_animation_time = m_squash_slowdown =
m_swatter_distance2 = m_swatter_duration = m_squash_slowdown =
m_squash_duration = UNDEFINED;
m_gravity_center_shift = Vec3(UNDEFINED);
m_has_skidmarks = true;
m_swatter_count = -1;
m_version = 0;
m_color = video::SColor(255, 0, 0, 0);
m_shape = 32; // close enough to a circle.
@ -452,10 +450,6 @@ void KartProperties::getAllData(const XMLNode * root)
if(const XMLNode *swatter_node= root->getNode("swatter"))
{
swatter_node->get("duration", &m_swatter_duration );
swatter_node->get("count", &m_swatter_count );
swatter_node->get("animation-time", &m_swatter_animation_time);
swatter_node->get("item-animation-time",
&m_swatter_item_animation_time);
swatter_node->get("squash-duration", &m_squash_duration );
swatter_node->get("squash-slowdown", &m_squash_slowdown );
if(swatter_node->get("distance", &m_swatter_distance2) )
@ -626,12 +620,9 @@ void KartProperties::checkAllSet(const std::string &filename)
CHECK_NEG(m_nitro_duration, "nitro duration" );
CHECK_NEG(m_nitro_fade_out_time, "nitro fade-out-time" );
CHECK_NEG(m_swatter_distance2, "swatter distance" );
CHECK_NEG(m_swatter_animation_time, "swatter animation-time" );
CHECK_NEG(m_swatter_item_animation_time,"swatter item-animation-time" );
CHECK_NEG(m_swatter_duration, "swatter duration" );
CHECK_NEG(m_swatter_count, "swatter count" );
CHECK_NEG(m_squash_duration, "swatter squash-duration" );
CHECK_NEG(m_squash_slowdown, "swatter squash-slowdown" );
CHECK_NEG(m_squash_duration, "squash-duration" );
CHECK_NEG(m_squash_slowdown, "squash-slowdown" );
CHECK_NEG(m_rescue_height, "rescue height" );
CHECK_NEG(m_rescue_time, "rescue time" );

View File

@ -201,8 +201,6 @@ private:
float m_nitro_fade_out_time;
/** Square of the maximum distance a swatter can operate. */
float m_swatter_distance2;
/** How often the swatter can be fired. */
int m_swatter_count;
/** How long the swatter lasts. */
float m_swatter_duration;
/** How long a kart will remain squashed. */
@ -210,10 +208,6 @@ private:
/** The slowdown to apply while a kart is squashed. The new maxspeed
* is max_speed*m_squash_slowdown. */
float m_squash_slowdown;
/** Animation time for the swatter. */
float m_swatter_animation_time;
/** How long the item swatting animation will last. */
float m_swatter_item_animation_time;
/** Engine sound effect. */
std::string m_engine_sfx_type;
@ -632,9 +626,6 @@ public:
* can hit karts. */
float getSwatterDistance2() const { return m_swatter_distance2; }
/** Returns how often a swatter can be used. */
int getSwatterCount() const { return m_swatter_count; }
/** Returns how long a swatter will stay attached/ready to be used. */
float getSwatterDuration() const { return m_swatter_duration; }
@ -644,12 +635,6 @@ public:
/** Returns the slowdown of a kart that is squashed. */
float getSquashSlowdown() const {return m_squash_slowdown; }
/** Returns how long it takes for the swatter to hit a target. */
float getSwatterAnimationTime() const { return m_swatter_animation_time; }
/** Returns how long it takes for the swatter to swat at an item. */
float getSwatterItemAnimationTime() const
{return m_swatter_item_animation_time; }
bool hasRandomWheels() const { return m_has_rand_wheels; }
}; // KartProperties

View File

@ -52,7 +52,7 @@
#include "config/stk_config.hpp"
#include "config/user_config.hpp"
#include "config/player.hpp"
#include "graphics/hardware_skinning.hpp" // BOUM
#include "graphics/hardware_skinning.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/material_manager.hpp"
#include "guiengine/engine.hpp"

View File

@ -153,7 +153,6 @@ void MainLoop::run()
PROFILER_POP_CPU_MARKER();
PROFILER_SYNC_FRAME();
//printf("--- end frame ---\n"); // BOUM
}
} // while !m_exit

View File

@ -31,7 +31,7 @@
#include "challenges/unlock_manager.hpp"
#include "config/user_config.hpp"
#include "graphics/camera.hpp"
#include "graphics/hardware_skinning.hpp" // BOUM
#include "graphics/hardware_skinning.hpp"
#include "io/file_manager.hpp"
#include "items/projectile_manager.hpp"
#include "karts/controller/default_ai_controller.hpp"