1 /*
2  * Copyright 2011-2012 Arx Libertatis Team (see the AUTHORS file)
3  *
4  * This file is part of Arx Libertatis.
5  *
6  * Arx Libertatis 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 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Arx Libertatis 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
17  * along with Arx Libertatis.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 /* Based on:
20 ===========================================================================
21 ARX FATALIS GPL Source Code
22 Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
23 
24 This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
25 
26 Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
27 License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
28 
29 Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
30 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
31 
32 You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code.  If not, see
33 <http://www.gnu.org/licenses/>.
34 
35 In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
36 additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
37 Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
38 
39 If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
40 ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
41 ===========================================================================
42 */
43 // Copyright (c) 1999-2001 ARKANE Studios SA. All rights reserved
44 
45 #include "graphics/spells/Spells10.h"
46 
47 #include <algorithm>
48 
49 #include "core/GameTime.h"
50 
51 #include "game/EntityManager.h"
52 
53 #include "graphics/Math.h"
54 #include "graphics/data/TextureContainer.h"
55 #include "graphics/effects/SpellEffects.h"
56 #include "graphics/spells/Spells07.h"
57 #include "graphics/spells/Spells09.h"
58 #include "graphics/particle/ParticleEffects.h"
59 
60 #include "scene/Interactive.h"
61 
62 //-----------------------------------------------------------------------------
63 //-----------------------------------------------------------------------------
CMassLightning(long nbmissiles)64 CMassLightning::CMassLightning(long nbmissiles)
65 {
66 	SetDuration(2000);
67 	pTab = new CLightning*[10];
68 	number = std::min(10L, nbmissiles);
69 
70 	for (int i = 0; i < number; i++)
71 	{
72 		pTab[i] = new CLightning();
73 		pTab[i]->fDamage = 2;
74 	}
75 }
76 
77 //-----------------------------------------------------------------------------
Create(Vec3f aePos,float afBeta=0)78 void CMassLightning::Create(Vec3f aePos, float afBeta = 0) {
79 
80 	(void)afBeta;
81 
82 	long lMax = 0;
83 	Vec3f eTarget;
84 	float ft = 360.0f / (float)number;
85 
86 	for (int i = 0; i < number; i++)
87 	{
88 		eTarget.x = aePos.x - EEsin(radians(i * ft)) * 500.0f;
89 		eTarget.y = aePos.y;
90 		eTarget.z = aePos.z + EEcos(radians(i * ft)) * 500.0f;
91 		pTab[i]->Create(aePos, eTarget, 0);
92 		long lTime = ulDuration + Random::get(0, 5000);
93 		pTab[i]->SetDuration(lTime);
94 		lMax = std::max(lMax, lTime);
95 		pTab[i]->spellinstance = this->spellinstance;
96 		pTab[i]->SetColor1(1.f, 0.75f, 0.75f); // middle
97 		pTab[i]->SetColor2(0.3f, 0.f, 0.f); // extremities
98 	}
99 
100 	SetDuration(lMax + 1000);
101 }
102 
103 //-----------------------------------------------------------------------------
Update(unsigned long _ulTime)104 void CMassLightning::Update(unsigned long _ulTime)
105 {
106 	for (int i = 0; i < number; i++)
107 	{
108 		pTab[i]->Update(_ulTime);
109 	}
110 }
111 
112 //-----------------------------------------------------------------------------
Render()113 float CMassLightning::Render()
114 {
115 	for (int i = 0; i < number; i++)
116 	{
117 		pTab[i]->Render();
118 	}
119 
120 	return 1;
121 }
122 
CControlTarget()123 CControlTarget::CControlTarget() {
124 
125 	eSrc = Vec3f::ZERO;
126 	eTarget = Vec3f::ZERO;
127 
128 	SetDuration(8000);
129 	ulCurrentTime = ulDuration + 1;
130 
131 	tex_mm = TextureContainer::Load("graph/obj3d/textures/(fx)_ctrl_target");
132 
133 	fColor[0] = 1;
134 	fColor[1] = 1;
135 	fColor[2] = 0;
136 
137 	fColor1[0] = 0.8f;
138 	fColor1[1] = 0.6f;
139 	fColor1[2] = 0.2f;
140 }
141 
Create(Vec3f aeSrc,float afBeta)142 void CControlTarget::Create(Vec3f aeSrc, float afBeta) {
143 
144 	SetDuration(ulDuration);
145 
146 	eSrc = aeSrc;
147 
148 	fBeta = afBeta;
149 	fBetaRad = radians(fBeta);
150 	fBetaRadCos = (float) cos(fBetaRad);
151 	fBetaRadSin = (float) sin(fBetaRad);
152 
153 	fSize = 1;
154 	bDone = true;
155 	eTarget = eSrc + Vec3f(-fBetaRadSin * 1000.f, 100.f, fBetaRadCos * 1000.f);
156 
157 	for(size_t i = 1; i < entities.size(); i++) {
158 		if(entities[i]) {
159 			eTarget = entities[i]->pos;
160 		}
161 	}
162 
163 	end = 20 - 1;
164 	v1a[0].p = eSrc + Vec3f(0.f, 100.f, 0.f);
165 	v1a[end].p = eTarget;
166 
167 	Vec3f h;
168 	Vec3f s = eSrc;
169 	Vec3f e = eSrc;
170 	int i = 0;
171 	while(Visible(&s, &e, NULL, &h) && i < 20) {
172 		e.x -= fBetaRadSin * 50;
173 		e.z += fBetaRadCos * 50;
174 		i++;
175 	}
176 
177 	pathways[0].p = eSrc + Vec3f(0.f, 100.f, 0.f);
178 	pathways[9].p = eTarget;
179 	Split(pathways, 0, 9, 150);
180 
181 	for(int i = 0; i < 9; i++) {
182 		if(pathways[i].p.y >= eSrc.y + 150) {
183 			pathways[i].p.y = eSrc.y + 150;
184 		}
185 	}
186 
187 	fTrail = 0;
188 }
189 
Update(unsigned long _ulTime)190 void CControlTarget::Update(unsigned long _ulTime) {
191 	ulCurrentTime += _ulTime;
192 }
193 
194 //---------------------------------------------------------------------
Render()195 float CControlTarget::Render()
196 {
197 	int i = 0;
198 
199 	GRenderer->SetCulling(Renderer::CullNone);
200 	GRenderer->SetRenderState(Renderer::DepthWrite, false);
201 	GRenderer->SetRenderState(Renderer::AlphaBlending, true);
202 	GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
203 	GRenderer->SetTexture(0, tex_mm);
204 
205 	// -------------------
206 	fTrail += 1;
207 
208 	if (fTrail >= 300) fTrail = 0;
209 
210 	int n = BEZIERPrecision;
211 	float delta = 1.0f / n;
212 
213 	fTrail = (ulCurrentTime * fOneOnDuration) * 9 * (n + 2);
214 
215 	Vec3f v;
216 
217 	int arx_check_init = -1;
218 	Vec3f newpos = Vec3f::ZERO;
219 	Vec3f lastpos = pathways[0].p;
220 
221 	for (i = 0; i < 9; i++)
222 	{
223 		int kp		= i;
224 		int kpprec	= (i > 0) ? kp - 1 : kp ;
225 		int kpsuiv	= kp + 1 ;
226 		int kpsuivsuiv = (i < (9 - 2)) ? kpsuiv + 1 : kpsuiv;
227 
228 		for (int toto = 1; toto < n; toto++)
229 		{
230 			if (fTrail < i * n + toto) break;
231 
232 			float t = toto * delta;
233 
234 			float t1 = t;
235 			float t2 = t1 * t1 ;
236 			float t3 = t2 * t1 ;
237 			float f0 = 2.f * t3 - 3.f * t2 + 1.f ;
238 			float f1 = -2.f * t3 + 3.f * t2 ;
239 			float f2 = t3 - 2.f * t2 + t1 ;
240 			float f3 = t3 - t2 ;
241 
242 			float val = pathways[kpsuiv].p.x;
243 			float p0 = 0.5f * (val - pathways[kpprec].p.x) ;
244 			float p1 = 0.5f * (pathways[kpsuivsuiv].p.x - pathways[kp].p.x) ;
245 			v.x = f0 * pathways[kp].p.x + f1 * val + f2 * p0 + f3 * p1 ;
246 
247 			val = pathways[kpsuiv].p.y ;
248 			p0 = 0.5f * (val - pathways[kpprec].p.y) ;
249 			p1 = 0.5f * (pathways[kpsuivsuiv].p.y - pathways[kp].p.y) ;
250 			v.y = f0 * pathways[kp].p.y + f1 * val + f2 * p0 + f3 * p1 ;
251 
252 			val = pathways[kpsuiv].p.z ;
253 			p0 = 0.5f * (val - pathways[kpprec].p.z) ;
254 			p1 = 0.5f * (pathways[kpsuivsuiv].p.z - pathways[kp].p.z) ;
255 			v.z = f0 * pathways[kp].p.z + f1 * val + f2 * p0 + f3 * p1 ;
256 
257 			newpos = v;
258 
259 			if(fTrail - (i * n + toto) <= 70) {
260 				float c = 1.0f - (fTrail - (i * n + toto)) / 70.0f;
261 				PARTICLE_DEF * pd = createParticle();
262 				if(pd) {
263 					pd->ov = lastpos;
264 					pd->siz = 5 * c;
265 					pd->tolive = Random::get(10, 110);
266 					pd->tc = tex_mm;
267 					pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING;
268 					pd->fparam = 0.0000001f;
269 					pd->rgb = Color3f::gray(c);
270 				}
271 			}
272 
273 			std::swap(lastpos, newpos);
274 			++arx_check_init;
275 
276 			PARTICLE_DEF * pd = createParticle();
277 			if(pd) {
278 				pd->ov = lastpos;
279 				pd->siz = 5;
280 				pd->tolive = Random::get(10, 110);
281 				pd->tc = tex_mm;
282 				pd->special = FADE_IN_AND_OUT | ROTATING | MODULATE_ROTATION | DISSIPATING;
283 				pd->fparam = 0.0000001f;
284 				pd->rgb = Color3f::gray(0.1f);
285 			}
286 		}
287 	}
288 
289 	arx_assert(arx_check_init >= 0);
290 
291 	eCurPos = lastpos;
292 
293 	return 1;
294 }
295 
296 //---------------------------------------------------------------------
~CMassIncinerate()297 CMassIncinerate::~CMassIncinerate()
298 {
299 }
300 
301 //---------------------------------------------------------------------
Create(Vec3f aePos,float afBeta=0)302 void CMassIncinerate::Create(Vec3f aePos, float afBeta = 0) {
303 
304 	(void)afBeta;
305 
306 	aePos.y += 150.0f;
307 
308 	for (int i = 0; i < 10; i++)
309 	{
310 		pTabIncinerate[i]->Create(aePos, i * 36.f);
311 	}
312 }
313 
314 //---------------------------------------------------------------------
Update(unsigned long _ulTime)315 void CMassIncinerate::Update(unsigned long _ulTime)
316 {
317 	for (int i = 0; i < 10; i++)
318 	{
319 		pTabIncinerate[i]->Update(_ulTime);
320 	}
321 
322 }
323 
324 //---------------------------------------------------------------------
Render()325 float CMassIncinerate::Render()
326 {
327 	for (int i = 0; i < 10; i++)
328 	{
329 		pTabIncinerate[i]->Render();
330 	}
331 
332 	return 0;
333 }
334 
335