1 ////////////////////////////////////////////////////////////////////////////////
2 //    Scorched3D (c) 2000-2011
3 //
4 //    This file is part of Scorched3D.
5 //
6 //    Scorched3D is free software; you can redistribute it and/or modify
7 //    it under the terms of the GNU General Public License as published by
8 //    the Free Software Foundation; either version 2 of the License, or
9 //    (at your option) any later version.
10 //
11 //    Scorched3D is distributed in the hope that it will be useful,
12 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //    GNU General Public License for more details.
15 //
16 //    You should have received a copy of the GNU General Public License along
17 //    with this program; if not, write to the Free Software Foundation, Inc.,
18 //    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 ////////////////////////////////////////////////////////////////////////////////
20 
21 #include <sprites/ExplosionNukeRenderer.h>
22 #include <sprites/ExplosionTextures.h>
23 #include <client/ScorchedClient.h>
24 #include <common/Defines.h>
25 #include <graph/OptionsDisplay.h>
26 #include <landscape/Landscape.h>
27 #include <landscapemap/LandscapeMaps.h>
28 #include <math.h>
29 
30 static const int AlphaSteps = int(ExplosionNukeRenderer_STEPS * 0.9f);
31 
ExplosionNukeRendererEntry(Vector & position,float size)32 ExplosionNukeRendererEntry::ExplosionNukeRendererEntry(
33 	Vector &position, float size) :
34 	totalTime_(0.0f), size_(size),
35 	startPosition_(position), cloudRotation_(0.0f)
36 {
37 	float rot = RAND * 3.14f * 2.0f;
38 	float width = RAND * 0.5f + 1.0f;
39 
40 	cloudRotation_ = RAND * 360.0f;
41 	rotation_[0] = getFastSin(rot) * width;
42 	rotation_[1] = getFastCos(rot) * width;
43 }
44 
~ExplosionNukeRendererEntry()45 ExplosionNukeRendererEntry::~ExplosionNukeRendererEntry()
46 {
47 }
48 
simulate(Particle * particle,float time)49 void ExplosionNukeRendererEntry::simulate(Particle *particle, float time)
50 {
51 	totalTime_ += time;
52 	cloudRotation_ += time * 5.0f;
53 
54 	int position = int((totalTime_ / (16.0f / 3.0f)) *
55 		float(ExplosionNukeRenderer_STEPS));
56 	if (position >= ExplosionNukeRenderer_STEPS)
57 		position = ExplosionNukeRenderer_STEPS - 1;
58 
59 	float z = ExplosionNukeRenderer::positions_[position][2] * (10.0f + size_) / 30.0f;
60 	float w = ExplosionNukeRenderer::positions_[position][0] + (size_ / 2.0f);
61 	particle->position_[0] = startPosition_[0] + rotation_[0] * w;
62 	particle->position_[1] = startPosition_[1] + rotation_[1] * w;
63 	particle->position_[2] = startPosition_[2] + z;
64 }
65 
66 Vector *ExplosionNukeRenderer::positions_ = 0;
67 
ExplosionNukeRenderer(Vector & position,float size,GLTextureSet * set,bool animate)68 ExplosionNukeRenderer::ExplosionNukeRenderer(Vector &position, float size,
69 	GLTextureSet *set,
70 	bool animate)
71 	: set_(set), animate_(animate), totalTime_(0.0f), time_(0.0f), position_(position), size_(size)
72 {
73 	position_[2] -= size_;
74 	float height = ScorchedClient::instance()->getLandscapeMaps().
75 		getGroundMaps().getHeight((int) position_[0], (int) position_[1]).asFloat();
76 	if (position_[2] < height) position_[2] = height;
77 
78 	if (!positions_)
79 	{
80 		positions_ = new Vector[ExplosionNukeRenderer_STEPS];
81 
82 		float zPos = 0.0f;
83 		float width = 0.0f;
84 
85 		for (int i=0; i<ExplosionNukeRenderer_STEPS; i++)
86 		{
87 			Vector pos;
88 			pos[0] = width;
89 			pos[1] = 0.0f;
90 			pos[2] = zPos;
91 
92 			if (i > (ExplosionNukeRenderer_STEPS * (0.3f))){
93 				width += 0.5f;
94 
95 			}else{
96 
97 				zPos += 2.0f;
98 			}
99 
100 			positions_[i] = pos;
101 		}
102 	}
103 
104 	emitter_.setAttributes(
105 		5.0f, 5.0f, // Life
106 		0.2f, 0.5f, // Mass
107 		0.01f, 0.02f, // Friction
108 		Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, 0.0f), // Velocity
109 		Vector(1.0f, 1.0f, 1.0f), 0.3f, // StartColor1
110 		Vector(1.0f, 1.0f, 1.0f), 0.2f, // StartColor2
111 		Vector(1.0f, 1.0f, 1.0f), 0.0f, // EndColor1
112 		Vector(1.0f, 1.0f, 1.0f), 0.0f, // EndColor2
113 		2.0f, 2.0f, 3.0f, 3.0f, // Start Size
114 		4.0f, 4.0f, 6.0f, 6.0f, // EndSize
115 		Vector(0.0f, 0.0f, 100.0f), // Gravity
116 		false,
117 		false);
118 }
119 
~ExplosionNukeRenderer()120 ExplosionNukeRenderer::~ExplosionNukeRenderer()
121 {
122 }
123 
draw(Action * action)124 void ExplosionNukeRenderer::draw(Action *action)
125 {
126 }
127 
simulate(Action * action,float frameTime,bool & remove)128 void ExplosionNukeRenderer::simulate(Action *action, float frameTime, bool &remove)
129 {
130 	float AddSmokeTime = 0.08f;
131 	int SmokesPerTime = 14;
132 	if (OptionsDisplay::instance()->getEffectsDetail() == 0)
133 	{
134 		SmokesPerTime = 8;
135 	}
136 	else if (OptionsDisplay::instance()->getEffectsDetail() == 2)
137 	{
138 		SmokesPerTime = 18;
139 	}
140 
141 	totalTime_ += frameTime;
142 	time_ += frameTime;
143 
144 	while (time_ > AddSmokeTime)
145 	{
146 		time_ -= AddSmokeTime;
147 
148 		// Add any new entries
149 		if (totalTime_ > 1.25f)
150 		{
151 			if (totalTime_ < 2.25f)
152 			{
153 				emitter_.emitMushroom(
154 					position_,
155 					ScorchedClient::instance()->getParticleEngine(),
156 					SmokesPerTime,
157 					size_,
158 					set_,
159 					animate_);
160 			}
161 			else remove = true;
162 		}
163 	}
164 }
165