1 //
2 // SuperTuxKart - a fun racing game with go-kart
3 // Copyright (C) 2004-2015 Steve Baker <sjbaker1@airmail.net>
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 3
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 #include "graphics/explosion.hpp"
20
21 #include "audio/sfx_base.hpp"
22 #include "audio/sfx_manager.hpp"
23 #include "config/stk_config.hpp"
24 #include "config/user_config.hpp"
25 #include "graphics/irr_driver.hpp"
26 #include "graphics/material.hpp"
27 #include "graphics/material_manager.hpp"
28 #include "graphics/particle_emitter.hpp"
29 #include "graphics/particle_kind_manager.hpp"
30 #include "graphics/stk_particle.hpp"
31 #include "items/projectile_manager.hpp"
32 #include "race/race_manager.hpp"
33 #include "utils/vec3.hpp"
34
35
36 /** Creates an explosion effect. */
Explosion(const Vec3 & coord,const char * explosion_sound,const char * particle_file)37 Explosion::Explosion(const Vec3& coord, const char* explosion_sound, const char * particle_file)
38 : HitSFX(coord, explosion_sound)
39 {
40 // short emision time, explosion, not constant flame
41
42 m_explosion_ticks = stk_config->time2Ticks(2.0f);
43 m_remaining_ticks = stk_config->time2Ticks(0.1f);
44 m_emission_frames = 0;
45
46 #ifndef SERVER_ONLY
47 std::string filename = particle_file;
48
49 #ifdef MOBILE_STK
50 // Use a lower quality effect on mobile for better performance
51 if (filename == "explosion.xml" ||
52 filename == "explosion_bomb.xml" ||
53 filename == "explosion_cake.xml")
54 {
55 filename = "explosion_low.xml";
56 }
57 #endif
58
59 ParticleKindManager* pkm = ParticleKindManager::get();
60 ParticleKind* particles = pkm->getParticles(filename);
61 m_emitter = NULL;
62
63 if (UserConfigParams::m_particles_effects > 1)
64 {
65 m_emitter = new ParticleEmitter(particles, coord, NULL);
66 m_emitter->getNode()->setPreGenerating(false);
67 }
68 #endif
69 } // Explosion
70
71 //-----------------------------------------------------------------------------
72 /** Destructor stops the explosion sfx from being played and frees its memory.
73 */
~Explosion()74 Explosion::~Explosion()
75 {
76 #ifndef SERVER_ONLY
77 if(m_emitter)
78 {
79 delete m_emitter;
80 }
81 #endif
82 } // ~Explosion
83
84 //-----------------------------------------------------------------------------
85 /** Updates the explosion, called one per time step.
86 * \param dt Time step size.
87 * \return true If the explosion is finished.
88 */
updateAndDelete(int ticks)89 bool Explosion::updateAndDelete(int ticks)
90 {
91 // The explosion sfx is shorter than the particle effect,
92 // so no need to save the result of the update call.
93 HitSFX::updateAndDelete(ticks);
94
95 m_emission_frames++;
96 m_remaining_ticks -= ticks;
97
98 // Do nothing more if the animation is still playing
99 if (m_remaining_ticks>0) return false;
100
101 // Otherwise check that the sfx has finished, otherwise the
102 // sfx will get aborted 'in the middle' when this explosion
103 // object is removed.
104 if (m_remaining_ticks > -m_explosion_ticks)
105 {
106 #ifndef SERVER_ONLY
107 // if framerate is very low, emit for at least a few frames, in case
108 // burst time is lower than the time of 1 frame
109 if (m_emission_frames > 2 && m_emitter != NULL)
110 {
111 // Stop the emitter and wait a little while for all particles to have time to fade out
112 m_emitter->getNode()->getEmitter()->setMinParticlesPerSecond(0);
113 m_emitter->getNode()->getEmitter()->setMaxParticlesPerSecond(0);
114 }
115 #endif
116 }
117 else
118 {
119 // Sound and animation finished, node can be removed now.
120 // Returning true will cause this node to be deleted by
121 // the projectile manager.
122 return true; // finished
123 }
124
125 return false; // not finished
126 } // updateAndDelete
127
128