diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d22d16c8..3c1348123 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,6 +203,7 @@ add_executable(supertuxkart src/graphics/explosion.hpp src/graphics/hardware_skinning.cpp src/graphics/hardware_skinning.hpp + src/graphics/hit_effect.hpp src/graphics/irr_driver.cpp src/graphics/irr_driver.hpp src/graphics/lod_node.cpp diff --git a/src/Makefile.am b/src/Makefile.am index c761570b3..22a402baf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -67,6 +67,7 @@ supertuxkart_SOURCES = \ graphics/explosion.hpp \ graphics/hardware_skinning.cpp \ graphics/hardware_skinning.hpp \ + graphics/hit_effect.hpp \ graphics/irr_driver.cpp \ graphics/irr_driver.hpp \ graphics/lod_node.cpp \ diff --git a/src/graphics/explosion.cpp b/src/graphics/explosion.cpp index f1f276eeb..cc8ca26c7 100644 --- a/src/graphics/explosion.cpp +++ b/src/graphics/explosion.cpp @@ -35,6 +35,7 @@ const float burst_time = 0.1f; /** Creates an explosion effect. */ Explosion::Explosion(const Vec3& coord, const char* explosion_sound, bool player_kart_hit) + : HitEffect(coord, explosion_sound, player_kart_hit) { // short emision time, explosion, not constant flame m_remaining_time = burst_time; @@ -101,8 +102,9 @@ Explosion::~Explosion() //----------------------------------------------------------------------------- /** Updates the explosion, called one per time step. * \param dt Time step size. + * \return true If the explosion is finished. */ -void Explosion::update(float dt) +bool Explosion::update(float dt) { m_remaining_time -= dt; @@ -126,7 +128,7 @@ void Explosion::update(float dt) // Do nothing more if the animation is still playing - if (m_remaining_time>0) return; + 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 @@ -147,7 +149,8 @@ void Explosion::update(float dt) // Sound and animation finished --> remove node irr_driver->removeNode(m_node); m_node = NULL; - projectile_manager->FinishedExplosion(); - return; + return true; // finished } + + return false; // not finished } // update diff --git a/src/graphics/explosion.hpp b/src/graphics/explosion.hpp index 4af33ec68..56c1b05c3 100644 --- a/src/graphics/explosion.hpp +++ b/src/graphics/explosion.hpp @@ -20,6 +20,7 @@ #ifndef HEADER_EXPLOSION_HPP #define HEADER_EXPLOSION_HPP +#include "graphics/hit_effect.hpp" #include "utils/no_copy.hpp" namespace irr @@ -36,7 +37,7 @@ const float explosion_time = 1.5f; /** * \ingroup graphics */ -class Explosion : public NoCopy +class Explosion : public HitEffect { private: SFXBase* m_explode_sound; @@ -47,8 +48,7 @@ private: public: Explosion(const Vec3& coord, const char* explosion_sound, bool player_hit); ~Explosion(); - void update (float delta_t); - int inUse (); + bool update (float delta_t); bool hasEnded () { return m_remaining_time <= -explosion_time; } } ; diff --git a/src/graphics/hit_effect.hpp b/src/graphics/hit_effect.hpp new file mode 100644 index 000000000..1a68b1d55 --- /dev/null +++ b/src/graphics/hit_effect.hpp @@ -0,0 +1,48 @@ +// $Id$ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2011 Joerg Henrichs +// +// 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. + +#ifndef HEADER_HIT_EFFECT_HPP +#define HEADER_HIT_EFFECT_HPP + +#include "utils/no_copy.hpp" + +class Vec3; + +/** + * \ingroup graphics + * A small interface for effects to be used when a kart is hit. That + * includes a sound effect only, or a graphical effect (like an + * explosion). + */ +class HitEffect: public NoCopy +{ +public: + /** Constructor for a hit effect. */ + HitEffect(const Vec3& coord, const char* explosion_sound, + bool player_hit) {}; + virtual ~HitEffect() {}; + /** Updates a hit effect. Called once per frame. + * \param dt Time step size. + * \return True if the hit effect is finished and can be removed. */ + virtual bool update (float dt) = 0; +}; // HitEffect + +#endif + +/* EOF */ diff --git a/src/ide/vc9/supertuxkart.vcproj b/src/ide/vc9/supertuxkart.vcproj index 967e41342..7d1be5a04 100644 --- a/src/ide/vc9/supertuxkart.vcproj +++ b/src/ide/vc9/supertuxkart.vcproj @@ -1784,6 +1784,10 @@ RelativePath="..\..\graphics\hardware_skinning.hpp" > + + diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index 17687c974..067ee095d 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -179,7 +179,7 @@ void Attachment::hitBanana(Item *item, int new_attachment) case ATTACH_BOMB: { add_a_new_item = false; - projectile_manager->newExplosion(m_kart->getXYZ(), "explosion", + projectile_manager->newHitEffect(m_kart->getXYZ(), "explosion", m_kart->getController()->isPlayerController()); m_kart->handleExplosion(m_kart->getXYZ(), /*direct_hit*/ true); clear(); @@ -313,7 +313,7 @@ void Attachment::update(float dt) } if(m_time_left<=0.0) { - projectile_manager->newExplosion(m_kart->getXYZ(), "explosion", + projectile_manager->newHitEffect(m_kart->getXYZ(), "explosion", m_kart->getController()->isPlayerController()); m_kart->handleExplosion(m_kart->getXYZ(), /*direct_hit*/ true); diff --git a/src/items/projectile_manager.cpp b/src/items/projectile_manager.cpp index 57c202979..f0ca612ce 100644 --- a/src/items/projectile_manager.cpp +++ b/src/items/projectile_manager.cpp @@ -20,6 +20,7 @@ #include "items/projectile_manager.hpp" #include "graphics/explosion.hpp" +#include "graphics/hit_effect.hpp" #include "items/bowling.hpp" #include "items/cake.hpp" #include "items/plunger.hpp" @@ -29,8 +30,6 @@ #include "network/network_manager.hpp" #include "network/race_state.hpp" -//static ssgSelector *find_selector ( ssgBranch *b ); - ProjectileManager *projectile_manager=0; void ProjectileManager::loadData() @@ -55,13 +54,13 @@ void ProjectileManager::cleanup() } m_active_projectiles.clear(); - for(Explosions::iterator i = m_active_explosions.begin(); - i != m_active_explosions.end(); ++i) + for(HitEffects::iterator i = m_active_hit_effects.begin(); + i != m_active_hit_effects.end(); ++i) { delete *i; } - m_active_explosions.clear(); + m_active_hit_effects.clear(); } // cleanup // ----------------------------------------------------------------------------- @@ -86,7 +85,8 @@ void ProjectileManager::update(float dt) if(! (*p)->hasHit()) { p++; continue; } if((*p)->needsExplosion()) { - newExplosion((*p)->getXYZ(), (*p)->getExplosionSound(), false ); + newHitEffect((*p)->getXYZ(), (*p)->getExplosionSound(), + /*player_kart_hit*/ false ); } Flyable *f=*p; Projectiles::iterator pNext=m_active_projectiles.erase(p); // returns the next element @@ -95,27 +95,19 @@ void ProjectileManager::update(float dt) } // while p!=m_active_projectiles.end() } - m_explosion_ended=false; - for(Explosions::iterator i = m_active_explosions.begin(); - i != m_active_explosions.end(); ++i) + HitEffects::iterator he = m_active_hit_effects.begin(); + while(he!=m_active_hit_effects.end()) { - (*i)->update(dt); - } - if(m_explosion_ended) - { - Explosions::iterator e; - e = m_active_explosions.begin(); - while(e!=m_active_explosions.end()) + // Update this hit effect. If it can be removed, remove it. + if((*he)->update(dt)) { - if(!(*e)->hasEnded()) { e++; continue;} - - delete *e; - - Explosions::iterator eNext = m_active_explosions.erase(e); - e = eNext; - } // while e!=m_active_explosions.end() - } // if m_explosion_ended - m_something_was_hit=false; + delete *he; + HitEffects::iterator next = m_active_hit_effects.erase(he); + he = next; + } // if hit effect finished + else // hit effect not finished, go to next one. + he++; + } // while hit effect != end } // update // ----------------------------------------------------------------------------- @@ -143,9 +135,9 @@ void ProjectileManager::updateServer(float dt) } // updateServer // ----------------------------------------------------------------------------- -/** Updates all rockets and explosions on the client. +/** Updates all rockets and hit effects on the client. * updateClient takes the information in race_state and updates all rockets - * (i.e. position, explosion etc) */ + * (i.e. position, hit effects etc) */ void ProjectileManager::updateClient(float dt) { m_something_was_hit = false; @@ -186,16 +178,20 @@ Flyable *ProjectileManager::newProjectile(Kart *kart, } // newProjectile // ----------------------------------------------------------------------------- -/** See if there is an old, unused explosion object available. If so, - * reuse this object, otherwise create a new one. */ -Explosion* ProjectileManager::newExplosion(const Vec3& coord, - const char* explosion_sound, +/** Creates a new hit effect. + * \param coord The coordinates where the hit effect (i.e. sound, graphics) + * should be placed). + * \param sfx The name of the sound effect to be played. + * \param player_kart_hit True of a player kart was hit. + */ +HitEffect* ProjectileManager::newHitEffect(const Vec3& coord, + const char *sfx, bool player_kart_hit) { - Explosion *e = new Explosion(coord, explosion_sound, player_kart_hit); - m_active_explosions.push_back(e); - return e; -} // newExplosion + HitEffect *he = new Explosion(coord, sfx, player_kart_hit); + m_active_hit_effects.push_back(he); + return he; +} // newHitEffect // ============================================================================= /** A general function which is only needed here, but diff --git a/src/items/projectile_manager.hpp b/src/items/projectile_manager.hpp index 76c70194c..f663d1441 100644 --- a/src/items/projectile_manager.hpp +++ b/src/items/projectile_manager.hpp @@ -33,7 +33,7 @@ namespace irr class Vec3; class Kart; -class Explosion; +class HitEffect; class Flyable; /** @@ -43,19 +43,19 @@ class ProjectileManager : public NoCopy { private: typedef std::vector Projectiles; - typedef std::vector Explosions; + typedef std::vector HitEffects; - // The list of all active projectiles, i.e. projectiles - // which are currently moving on the track + /** The list of all active projectiles, i.e. projectiles which are + * currently moving on the track. */ Projectiles m_active_projectiles; - // All active explosions, i.e. explosions which are currently - // being shown - Explosions m_active_explosions; + /** All active hit effects, i.e. hit effects which are currently + * being shown or have a sfx playing. */ + HitEffects m_active_hit_effects; scene::IMesh *m_explosion_model; + bool m_something_was_hit; - bool m_explosion_ended; void updateClient(float dt); void updateServer(float dt); public: @@ -63,19 +63,16 @@ public: ~ProjectileManager() {} /** Notifies the projectile manager that something needs to be removed. */ void notifyRemove () {m_something_was_hit=true; } - void FinishedExplosion() {m_explosion_ended =true; } - scene::IMesh* getExplosionModel() + scene::IMesh *getExplosionModel() { return m_explosion_model; } - unsigned int getNumProjectiles() const {return m_active_explosions.size();} - int getProjectileId (const std::string ident); void loadData (); void cleanup (); void update (float dt); Flyable* newProjectile (Kart *kart, PowerupManager::PowerupType type); - Explosion* newExplosion (const Vec3& coord, + HitEffect* newHitEffect (const Vec3& coord, const char* explosion_sound="explosion", bool is_player_kart_hit = false); void Deactivate (Flyable *p) {}