stk-code_catmod/src/graphics/explosion.cpp
curaga b56bf4dc53 Remove trailing space, git doesn't like it
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@12797 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2013-05-29 22:04:35 +00:00

143 lines
5.5 KiB
C++

//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "graphics/explosion.hpp"
#include "audio/sfx_base.hpp"
#include "audio/sfx_manager.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/material.hpp"
#include "graphics/material_manager.hpp"
#include "items/projectile_manager.hpp"
#include "race/race_manager.hpp"
#include "utils/vec3.hpp"
#include <IParticleSystemSceneNode.h>
const float burst_time = 0.1f;
/** Creates an explosion effect. */
Explosion::Explosion(const Vec3& coord, const char* explosion_sound)
: HitSFX(coord, explosion_sound)
{
// short emision time, explosion, not constant flame
m_remaining_time = burst_time;
m_node = irr_driver->addParticleNode();
m_node->grab();
#ifdef DEBUG
m_node->setName("explosion");
#endif
m_node->setPosition(coord.toIrrVector());
Material* m = material_manager->getMaterial("explode.png");
m_node->setMaterialTexture(0, m->getTexture());
m->setMaterialProperties(&(m_node->getMaterial(0)), NULL);
m_node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
scene::IParticleEmitter* em =
m_node->createSphereEmitter(core::vector3df(0.0f,0.0f,0.0f), 0.5f,
/* velocity in m/ms */core::vector3df(0.0f,0.005f,0.0f),
600, 900, // min max particles per sec
video::SColor(0, 0, 0, 0), // min colour
video::SColor(0, 0, 0, 0), // max colour
(int)((burst_time + explosion_time)
*1000.0f), // min life ms
(int)((burst_time + explosion_time)
*1000.0f), // max max life ms
90, // max angle
// min and max start size
core::dimension2df(0.3f, 0.3f),
core::dimension2df(0.75f, 0.75f)
);
m_node->setEmitter(em); // this grabs the emitter
em->drop(); // so we can drop it here without deleting it
scene::IParticleAffector* scale_affector =
m_node->createScaleParticleAffector(core::dimension2df(3.0f, 3.0f));
m_node->addAffector(scale_affector); // same goes for the affector
scale_affector->drop();
} // Explosion
//-----------------------------------------------------------------------------
/** Destructor stops the explosion sfx from being played and frees its memory.
*/
Explosion::~Explosion()
{
if(m_node)
{
m_node->drop();
// Remove from scene node by removing from parent.
irr_driver->removeNode(m_node);
m_node = NULL;
}
} // ~Explosion
//-----------------------------------------------------------------------------
/** Updates the explosion, called one per time step.
* \param dt Time step size.
* \return true If the explosion is finished.
*/
bool Explosion::updateAndDelete(float dt)
{
// The explosion sfx is shorter than the particle effect,
// so no need to save the result of the update call.
HitSFX::updateAndDelete(dt);
m_remaining_time -= dt;
if (m_remaining_time < 0.0f && m_remaining_time >= -explosion_time)
{
const int intensity = (int)(255-(m_remaining_time/-explosion_time)*255);
m_node->getMaterial(0).AmbientColor.setGreen(intensity);
m_node->getMaterial(0).DiffuseColor.setGreen(intensity);
m_node->getMaterial(0).EmissiveColor.setGreen(intensity);
m_node->getMaterial(0).AmbientColor.setBlue(intensity);
m_node->getMaterial(0).DiffuseColor.setBlue(intensity);
m_node->getMaterial(0).EmissiveColor.setBlue(intensity);
m_node->getMaterial(0).AmbientColor.setRed(intensity);
m_node->getMaterial(0).DiffuseColor.setRed(intensity);
m_node->getMaterial(0).EmissiveColor.setRed(intensity);
}
// Do nothing more if the animation is still playing
if (m_remaining_time>0) return false;
// Otherwise check that the sfx has finished, otherwise the
// sfx will get aborted 'in the middle' when this explosion
// object is removed.
if (m_remaining_time > -explosion_time)
{
// Stop the emitter and wait a little while for all particles to have time to fade out
m_node->getEmitter()->setMinParticlesPerSecond(0);
m_node->getEmitter()->setMaxParticlesPerSecond(0);
}
else
{
// Sound and animation finished, node can be removed now.
// Returning true will cause this node to be deleted by
// the projectile manager.
return true; // finished
}
return false; // not finished
} // updateAndDelete