Added hit effect that only plays a sfx. Simplified
projectile manager of special effects somewhat (now no more calls from a hit effect to the projectile manager are necessary). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9617 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
8b0a7f0b2e
commit
3161c79196
@ -68,6 +68,8 @@ supertuxkart_SOURCES = \
|
||||
graphics/hardware_skinning.cpp \
|
||||
graphics/hardware_skinning.hpp \
|
||||
graphics/hit_effect.hpp \
|
||||
graphics/hit_sfx.cpp \
|
||||
graphics/hit_sfx.hpp \
|
||||
graphics/irr_driver.cpp \
|
||||
graphics/irr_driver.hpp \
|
||||
graphics/lod_node.cpp \
|
||||
|
@ -33,14 +33,12 @@
|
||||
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)
|
||||
{
|
||||
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_player_kart_hit = player_kart_hit;
|
||||
|
||||
#ifdef DEBUG
|
||||
m_node->setName("explosion");
|
||||
@ -73,17 +71,6 @@ Explosion::Explosion(const Vec3& coord, const char* explosion_sound,
|
||||
m_node->createScaleParticleAffector(core::dimension2df(3.0f, 3.0f));
|
||||
m_node->addAffector(scale_affector); // same goes for the affector
|
||||
scale_affector->drop();
|
||||
|
||||
m_explode_sound = sfx_manager->createSoundSource( explosion_sound );
|
||||
m_explode_sound->position(coord);
|
||||
|
||||
// in multiplayer mode, sounds are NOT positional (because we have multiple listeners)
|
||||
// so the sounds of all AIs are constantly heard. So reduce volume of sounds.
|
||||
if (race_manager->getNumLocalPlayers() > 1)
|
||||
m_explode_sound->volume(m_player_kart_hit ? 1.0f : 0.5f);
|
||||
else
|
||||
m_explode_sound->volume(1.0f);
|
||||
m_explode_sound->play();
|
||||
} // Explosion
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -91,12 +78,6 @@ Explosion::Explosion(const Vec3& coord, const char* explosion_sound,
|
||||
*/
|
||||
Explosion::~Explosion()
|
||||
{
|
||||
if (m_explode_sound->getStatus() == SFXManager::SFX_PLAYING)
|
||||
{
|
||||
m_explode_sound->stop();
|
||||
}
|
||||
|
||||
sfx_manager->deleteSFX(m_explode_sound);
|
||||
} // ~Explosion
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -106,6 +87,10 @@ Explosion::~Explosion()
|
||||
*/
|
||||
bool Explosion::update(float dt)
|
||||
{
|
||||
// The explosion sfx is shorter than the particle effect,
|
||||
// so no need to save the result of the update call.
|
||||
HitSFX::update(dt);
|
||||
|
||||
m_remaining_time -= dt;
|
||||
|
||||
if (m_remaining_time < 0.0f && m_remaining_time >= -explosion_time)
|
||||
@ -133,11 +118,6 @@ bool Explosion::update(float dt)
|
||||
// Otherwise check that the sfx has finished, otherwise the
|
||||
// sfx will get aborted 'in the middle' when this explosion
|
||||
// object is removed.
|
||||
//if (m_explode_sound->getStatus() == SFXManager::SFX_PLAYING)
|
||||
//{
|
||||
// m_remaining_time = 0;
|
||||
//}
|
||||
//else
|
||||
if (m_remaining_time > -explosion_time)
|
||||
{
|
||||
// Stop the emitter and wait a little while for all particles to have time to fade out
|
||||
|
@ -20,7 +20,7 @@
|
||||
#ifndef HEADER_EXPLOSION_HPP
|
||||
#define HEADER_EXPLOSION_HPP
|
||||
|
||||
#include "graphics/hit_effect.hpp"
|
||||
#include "graphics/hit_sfx.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
namespace irr
|
||||
@ -37,16 +37,14 @@ const float explosion_time = 1.5f;
|
||||
/**
|
||||
* \ingroup graphics
|
||||
*/
|
||||
class Explosion : public HitEffect
|
||||
class Explosion : public HitSFX
|
||||
{
|
||||
private:
|
||||
SFXBase* m_explode_sound;
|
||||
float m_remaining_time;
|
||||
bool m_player_kart_hit;
|
||||
scene::IParticleSystemSceneNode *m_node;
|
||||
|
||||
public:
|
||||
Explosion(const Vec3& coord, const char* explosion_sound, bool player_hit);
|
||||
Explosion(const Vec3& coord, const char* explosion_sound);
|
||||
~Explosion();
|
||||
bool update (float delta_t);
|
||||
bool hasEnded () { return m_remaining_time <= -explosion_time; }
|
||||
|
@ -32,15 +32,28 @@ class Vec3;
|
||||
*/
|
||||
class HitEffect: public NoCopy
|
||||
{
|
||||
private:
|
||||
/** True if this effect affected a player kart. Used to play certain SFX
|
||||
* less loud if only an AI is hit. */
|
||||
bool m_player_kart_hit;
|
||||
|
||||
public:
|
||||
/** Constructor for a hit effect. */
|
||||
HitEffect(const Vec3& coord, const char* explosion_sound,
|
||||
bool player_hit) {};
|
||||
virtual ~HitEffect() {};
|
||||
/** Constructor for a hit effect. */
|
||||
HitEffect() {m_player_kart_hit = false; }
|
||||
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;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets that this SFX affects a player kart, which can be used to
|
||||
* make certain sfx louder/less loud. Default is that the affect
|
||||
* does not affect a player kart. */
|
||||
virtual void setPlayerKartHit() { m_player_kart_hit = true; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if this effect affects a player kart. */
|
||||
bool getPlayerKartHit() const { return m_player_kart_hit; }
|
||||
}; // HitEffect
|
||||
|
||||
#endif
|
||||
|
71
src/graphics/hit_sfx.cpp
Normal file
71
src/graphics/hit_sfx.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
// $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.
|
||||
|
||||
#include "graphics/hit_sfx.hpp"
|
||||
|
||||
#include "audio/sfx_base.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
|
||||
/** Creates a sound effect when something was hit. */
|
||||
HitSFX::HitSFX(const Vec3& coord, const char* explosion_sound)
|
||||
: HitEffect()
|
||||
{
|
||||
m_sfx = sfx_manager->createSoundSource( explosion_sound );
|
||||
m_sfx->position(coord);
|
||||
|
||||
// in multiplayer mode, sounds are NOT positional (because we have
|
||||
// multiple listeners) so the sounds of all AIs are constantly heard.
|
||||
// Therefore reduce volume of sounds.
|
||||
float vol = race_manager->getNumLocalPlayers() > 1 ? 0.5f : 1.0f;
|
||||
m_sfx->volume(vol);
|
||||
m_sfx->play();
|
||||
} // HitSFX
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Destructor stops the explosion sfx from being played and frees its memory.
|
||||
*/
|
||||
HitSFX::~HitSFX()
|
||||
{
|
||||
if (m_sfx->getStatus() == SFXManager::SFX_PLAYING)
|
||||
m_sfx->stop();
|
||||
|
||||
sfx_manager->deleteSFX(m_sfx);
|
||||
} // ~HitEffect
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Called if this hit effect is for a player kart (in which case it might be
|
||||
* played louder than for a non-player kart if split screen is used).
|
||||
* If this sfx is for a player kart in split screen, make it louder again.
|
||||
*/
|
||||
void HitSFX::setPlayerKartHit()
|
||||
{
|
||||
if(race_manager->getNumLocalPlayers())
|
||||
m_sfx->volume(1.0f);
|
||||
} // setPlayerKartHit
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updates the hit sfx, called one per time step.
|
||||
* \param dt Time step size.
|
||||
* \return true If the explosion is finished.
|
||||
*/
|
||||
bool HitSFX::update(float dt)
|
||||
{
|
||||
return m_sfx->getStatus() != SFXManager::SFX_PLAYING;
|
||||
} // update
|
46
src/graphics/hit_sfx.hpp
Normal file
46
src/graphics/hit_sfx.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
// $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_SFX_HPP
|
||||
#define HEADER_HIT_SFX_HPP
|
||||
|
||||
#include "graphics/hit_effect.hpp"
|
||||
|
||||
class SFXBase;
|
||||
|
||||
/**
|
||||
* \ingroup graphics
|
||||
*/
|
||||
class HitSFX : public HitEffect
|
||||
{
|
||||
private:
|
||||
/** The sfx to play. */
|
||||
SFXBase* m_sfx;
|
||||
|
||||
public:
|
||||
HitSFX(const Vec3& coord, const char* explosion_sound);
|
||||
~HitSFX();
|
||||
virtual bool update (float dt);
|
||||
virtual void setPlayerKartHit();
|
||||
|
||||
}; // HitSFX
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
@ -702,6 +702,10 @@
|
||||
RelativePath="..\..\graphics\hardware_skinning.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\graphics\hit_sfx.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\graphics\irr_driver.cpp"
|
||||
>
|
||||
@ -1788,6 +1792,10 @@
|
||||
RelativePath="..\..\graphics\hit_effect.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\graphics\hit_sfx.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\graphics\irr_driver.hpp"
|
||||
>
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "audio/sfx_base.hpp"
|
||||
#include "config/stk_config.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/explosion.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "items/attachment_manager.hpp"
|
||||
#include "items/projectile_manager.hpp"
|
||||
@ -179,8 +180,11 @@ void Attachment::hitBanana(Item *item, int new_attachment)
|
||||
case ATTACH_BOMB:
|
||||
{
|
||||
add_a_new_item = false;
|
||||
projectile_manager->newHitEffect(m_kart->getXYZ(), "explosion",
|
||||
m_kart->getController()->isPlayerController());
|
||||
HitEffect *he = new Explosion(m_kart->getXYZ(), "explosion");
|
||||
if(m_kart->getController()->isPlayerController())
|
||||
he->setPlayerKartHit();
|
||||
projectile_manager->addHitEffect(he);
|
||||
|
||||
m_kart->handleExplosion(m_kart->getXYZ(), /*direct_hit*/ true);
|
||||
clear();
|
||||
if(new_attachment==-1)
|
||||
@ -313,8 +317,10 @@ void Attachment::update(float dt)
|
||||
}
|
||||
if(m_time_left<=0.0)
|
||||
{
|
||||
projectile_manager->newHitEffect(m_kart->getXYZ(), "explosion",
|
||||
m_kart->getController()->isPlayerController());
|
||||
HitEffect *he = new Explosion(m_kart->getXYZ(), "explosion");
|
||||
if(m_kart->getController()->isPlayerController())
|
||||
he->setPlayerKartHit();
|
||||
projectile_manager->addHitEffect(he);
|
||||
m_kart->handleExplosion(m_kart->getXYZ(),
|
||||
/*direct_hit*/ true);
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <IMeshManipulator.h>
|
||||
#include <IMeshSceneNode.h>
|
||||
|
||||
#include "graphics/explosion.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/mesh_tools.hpp"
|
||||
#include "graphics/stars.hpp"
|
||||
@ -539,5 +540,13 @@ void Flyable::hit(Kart *kart_hit, PhysicalObject* object)
|
||||
}
|
||||
world->getTrack()->handleExplosion(getXYZ(), object);
|
||||
} // hit
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns the hit effect object to use when this objects hits something.
|
||||
* \returns The hit effect object, or NULL if no hit effect should be played.
|
||||
*/
|
||||
HitEffect* Flyable::getHitEffect() const
|
||||
{
|
||||
return new Explosion(getXYZ(), "explosion");
|
||||
} // getHitEffect
|
||||
|
||||
/* EOF */
|
||||
|
@ -35,6 +35,7 @@ using namespace irr;
|
||||
#include "tracks/terrain_info.hpp"
|
||||
|
||||
class FlyableInfo;
|
||||
class HitEffect;
|
||||
class Kart;
|
||||
class PhysicalObject;
|
||||
class XMLNode;
|
||||
@ -155,6 +156,7 @@ public:
|
||||
PowerupManager::PowerupType type);
|
||||
virtual void update (float);
|
||||
void updateFromServer(const FlyableInfo &f, float dt);
|
||||
HitEffect *getHitEffect() const;
|
||||
bool isOwnerImmunity(const Kart *kart_hit) const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -85,8 +85,8 @@ void ProjectileManager::update(float dt)
|
||||
if(! (*p)->hasHit()) { p++; continue; }
|
||||
if((*p)->needsExplosion())
|
||||
{
|
||||
newHitEffect((*p)->getXYZ(), (*p)->getExplosionSound(),
|
||||
/*player_kart_hit*/ false );
|
||||
HitEffect *he = (*p)->getHitEffect();
|
||||
addHitEffect(he);
|
||||
}
|
||||
Flyable *f=*p;
|
||||
Projectiles::iterator pNext=m_active_projectiles.erase(p); // returns the next element
|
||||
@ -176,47 +176,3 @@ Flyable *ProjectileManager::newProjectile(Kart *kart,
|
||||
m_active_projectiles.push_back(f);
|
||||
return f;
|
||||
} // newProjectile
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** 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)
|
||||
{
|
||||
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
|
||||
* it's not really a method, so I'll leave it here.
|
||||
*/
|
||||
/*
|
||||
static ssgSelector *find_selector ( ssgBranch *b )
|
||||
{
|
||||
if ( b == NULL )
|
||||
return NULL ;
|
||||
|
||||
if ( ! b -> isAKindOf ( ssgTypeBranch () ) )
|
||||
return NULL ;
|
||||
|
||||
if ( b -> isAKindOf ( ssgTypeSelector () ) )
|
||||
return (ssgSelector *) b ;
|
||||
|
||||
for ( int i = 0 ; i < b -> getNumKids() ; i++ )
|
||||
{
|
||||
ssgSelector *res = find_selector ( (ssgBranch *)(b ->getKid(i)) ) ;
|
||||
|
||||
if ( res != NULL )
|
||||
return res ;
|
||||
}
|
||||
|
||||
return NULL ;
|
||||
} // find_selector
|
||||
*/
|
||||
|
@ -53,8 +53,6 @@ private:
|
||||
* being shown or have a sfx playing. */
|
||||
HitEffects m_active_hit_effects;
|
||||
|
||||
scene::IMesh *m_explosion_model;
|
||||
|
||||
bool m_something_was_hit;
|
||||
void updateClient(float dt);
|
||||
void updateServer(float dt);
|
||||
@ -63,20 +61,18 @@ public:
|
||||
~ProjectileManager() {}
|
||||
/** Notifies the projectile manager that something needs to be removed. */
|
||||
void notifyRemove () {m_something_was_hit=true; }
|
||||
scene::IMesh *getExplosionModel()
|
||||
{
|
||||
return m_explosion_model;
|
||||
}
|
||||
void loadData ();
|
||||
void cleanup ();
|
||||
void update (float dt);
|
||||
Flyable* newProjectile (Kart *kart,
|
||||
PowerupManager::PowerupType type);
|
||||
HitEffect* newHitEffect (const Vec3& coord,
|
||||
const char* explosion_sound="explosion",
|
||||
bool is_player_kart_hit = false);
|
||||
void Deactivate (Flyable *p) {}
|
||||
void removeTextures ();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds a special hit effect to be shown.
|
||||
* \param hit_effect The hit effect to be added. */
|
||||
void addHitEffect(HitEffect *hit_effect)
|
||||
{ m_active_hit_effects.push_back(hit_effect); }
|
||||
};
|
||||
|
||||
extern ProjectileManager *projectile_manager;
|
||||
|
@ -423,7 +423,9 @@ void RubberBall::hit(Kart* kart, PhysicalObject* object)
|
||||
{
|
||||
// If the object is not the main target, only flatten the kart
|
||||
if(kart!=m_target)
|
||||
{
|
||||
kart->setSquash(m_st_squash_duration, m_st_squash_slowdown);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Else trigger the full explosion animation
|
||||
|
Loading…
Reference in New Issue
Block a user